I have a static ComboBox
in 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.
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
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
:
ViewModel
and load the static value back to ComboBox
?In WPF has support for arrays of objects in XAML through a markup extension. This corresponds to the x:ArrayExtension
XAML type 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:Array
use a static
member:
<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 ComboBox
with numbers Int32
type, it can be even shorter:
<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>
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.
With binding we have list of values as property of ViewModel object, which is set as DataContext
in terms of WPF. So, here is binding example:
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>
This solution was finely illustrated in previous answer by @AnatoliyNikolaev.
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:
<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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With