在 WPF 中执行静态 ComboBox 的有效方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22189412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:07:12  来源:igfitidea点击:

Effiecient way to do static ComboBox in WPF

c#wpfxamlcombobox

提问by Usher

I have a static ComboBoxin my wpf applicaiton, that loads space followed by 0-9. I have the following code it does the job what I need, but I dont feel its a great way to do. Any suggestion or opinion will be appreciated.

ComboBox我的 wpf 应用程序中有一个静态文件,它加载空间,然后是 0-9。我有以下代码,它可以完成我需要的工作,但我觉得这不是一个好方法。任何建议或意见将不胜感激。

Test.xaml

Test.xaml

<ComboBox Name="cbImportance" 
          Text="{Binding SelectedStory.ImportanceList, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource ErrorTemplate}" 
          Loaded="cbImportance_Loaded"
          Grid.Column="1"
          d:LayoutOverrides="Height" 
          Grid.ColumnSpan="2" 
          HorizontalAlignment="Stretch"
          Margin="0,9" 
          SelectionChanged="cbImportance_SelectionChanged" />

Test.xaml.cs

Test.xaml.cs

private void cbImportance_Loaded(object sender, RoutedEventArgs e)
{
    List<string> data = new List<string>();
    data.Add("");
    data.Add("0");
    data.Add("1");
    data.Add("2");
    data.Add("3");
    data.Add("4");
    data.Add("5");
    data.Add("6");
    data.Add("7");
    data.Add("8");
    data.Add("9");

    // ... Get the ComboBox reference.
    var cbImportance = sender as ComboBox;

    // ... Assign the ItemsSource to the List.
    cbImportance.ItemsSource = data;

    // ... Make the first item selected.
    cbImportance.SelectedIndex = 0;
}

Which one is the efficient way to load the static value in to ComboBox:

哪一种是将静态值加载到的有效方法ComboBox

  1. Through XAML (suggested by Anatoliy Nikolaev)
  2. xaml.cs (Like Above)
  3. Create constructor in ViewModeland load the static value back to ComboBox?
  1. 通过 XAML(由 Anatoliy Nikolaev 建议)
  2. xaml.cs(如上)
  3. 在其中创建构造函数ViewModel并将静态值加载回ComboBox?

回答by Anatoliy Nikolaev

In WPF has support for arrays of objects in XAML through a markup extension. This corresponds to the x:ArrayExtensionXAML type MSDN.

在 WPF 中,通过标记扩展支持 XAML 中的对象数组。这对应于x:ArrayExtensionXAML 类型MSDN

You can do this:

你可以这样做:

<Window ...
        xmlns:sys="clr-namespace:System;assembly=mscorlib">

<x:Array x:Key="ParametersArray" Type="{x:Type sys:String}">
    <sys:String>0</sys:String>
    <sys:String>1</sys:String>
    <sys:String>2</sys:String>
    <sys:String>3</sys:String>
    ...
</x:Array>

<ComboBox Name="ParameterComboBox"
          SelectedIndex="0"
          ItemsSource="{StaticResource ParametersArray}" ... />

For setting empty string in x:Arrayuse a staticmember:

用于在x:Array使用中设置空字符串static成员:

<x:Array x:Key="ParametersArray" Type="{x:Type sys:String}">
    <x:Static Member="sys:String.Empty" />
    <sys:String>0</sys:String>
    <sys:String>1</sys:String>
    <sys:String>2</sys:String>
    <sys:String>3</sys:String>
    ...
</x:Array>

If you need to define a static ComboBoxwith numbers Int32type, it can be even shorter:

如果你需要定义一个ComboBox数字Int32类型的静态,它可以更短:

<Window.Resources>
    <Int32Collection x:Key="Parameters">0,1,2,3,4,5,6,7,8,9</Int32Collection>
</Window.Resources>

<ComboBox Width="100" 
          Height="30" 
          ItemsSource="{StaticResource Parameters}" />

Or like this:

或者像这样:

<ComboBox Width="100" Height="30">
    <ComboBox.ItemsSource>
        <Int32Collection>0,1,2,3,4,5,6,7,8,9</Int32Collection>
    </ComboBox.ItemsSource>
</ComboBox>

回答by oxfn

There are many ways to use enumerable object as ItemsSource, based on {StaticResource}or {Binding}or other dependancy property. Binding is preferred way, because it meets MVVM approach, wich is recommended for WPF apps.

有很多方法可以使用可枚举对象作为 ItemsSource,基于{StaticResource}{Binding}或其他依赖属性。绑定是首选方式,因为它符合 MVVM 方法,推荐用于 WPF 应用程序。

MVVM way

MVVM方式

With binding we have list of values as property of ViewModel object, which is set as DataContextin terms of WPF. So, here is binding example:

通过绑定,我们将值列表作为 ViewModel 对象的属性,DataContext根据 WPF 设置。所以,这是绑定示例

ViewModel:

视图模型:

public class MyViewModel : INotifyPropertyChanged
{
    public ObservableCollection<SomeObject> Items
    {
        get { /* ... */ }
    }
    public SomeObject SelectedItem
    {
        get { /* ... */ }
        set { /* ... */ }
    }
}

View:

看法:

<Window
    x:Class="Project1.MainWindow">
    <ComboBox
        ItemsSource={Binding Items}
        SelectedItem={Binding SelectedItem} />
</Window>

String array as static resource

字符串数组作为静态资源

This solution was finely illustrated in previous answer by @AnatoliyNikolaev.

这个解决方案在@AnatoliyNikolaev 的先前回答中得到了很好的说明。

XmlDataProvider

XmlDataProvider

Sometimes you have to operate on complex values which have visible title. Putting it in ViewModel is senseless - better use XAML features. That's what it looks like:

有时您必须对具有可见标题的复杂值进行操作。将它放在 ViewModel 中是没有意义的 - 更好地使用 XAML 功能。这就是它的样子:

<Window>
    <Window.Resources>
        <XmlDataProvider x:Key="YesNo" XPath="Items">
            <x:XData>
                <Items xmlns="">
                    <Item Header="Yes" Value="1"/>
                    <Item Header="No" Value="0"/>
                </Items>
            </x:XData>
        </XmlDataProvider>
    </Window.Resources>
    <Grid>
        <ComboBox
            ItemsSource="{Binding Source={StaticResource YesNo},XPath=*,Mode=OneTime}"
            SelectedValue="{Binding Value,UpdateSourceTrigger=PropertyChanged}"
            SelectedValuePath="@Value"
            DisplayMemberPath="@Header">
    </Grid>
</Window>