I want to bind a combo box to a list of Device, List. I use,
m_ctrlCB.DataContext = m_List;
m_ctrlCB.DisplayMemberPath = "ToString()";
m_ctrlCB.SelectedValuePath = "ToString()"; // do I even need this?
I don't have any properties in De开发者_JAVA百科vice to bind to and it's not my class. However, they do override ToString to something that is suitable for displaying in the combobox (something like: "Class Device. Number 1".
However, what I wrote doesn't work. What I see in the combobox is blank items. My selectionChanged event does work AND e.AddedItems[0] really is a Device, so I'm close. How can I get something meaningful to display in the combox box.
I suppose I'd also be happy creating ComboBoxItems and adding them to the ComboBox if necessary. But if I go this route, how do I set the Display stuff and the actual object itself so I can get it when the user selects it from the combobox?
Bonus question. If instead of using ToString, I want to use GetDeviceNumber() and combine it with my own test so the user sees, Device #1 Device #2 how would I do this?
thanks, Dave
You don't have to set the DisplayMemberPath and the SelectedValuePath. Since your Device object overrides ToString(), it should display the correct string on its own.
EDIT:
To answer your "bonus question", one way to do this is to use an IValueConverter that calls the method you're interested in. The sample code below demonstrates this. I have here a combobox whose items are represented by a TextBlock (which shows the value for the ToString() method), as well as a Button (which shows the value for the GetDeviceNumber() method).
XAML:
<Window x:Class="StackOverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StackOverflow"
Title="MainWindow" Height="350" Width="525"
x:Name="window">
<ComboBox x:Name="cb">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}"/>
<Button>
<Button.Content>
<Binding>
<Binding.Converter>
<local:DeviceValueConverter/>
</Binding.Converter>
</Binding>
</Button.Content>
</Button>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Window>
Code-Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.cb.ItemsSource = new List<Device>()
{
new Device("Device1"),
new Device("Device2"),
new Device("Device3"),
};
}
}
public class Device
{
private string text;
public Device(string text)
{
this.text = text;
}
public string GetDeviceNumber() { return this.GetHashCode().ToString(); }
public override string ToString() { return this.text; }
}
public class DeviceValueConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Device)
{
return (value as Device).GetDeviceNumber();
}
return string.Empty;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
#endregion
}
One way you could do it would be to create a wrapper class and provide the appropriate properties on it. For example:
class DeviceWrapper
{
private Device device;
public DeviceWrapper(Device device)
{
this.device = device;
}
public int DeviceNumber
{
return this.device.GetDeviceNumber();
}
// etc...
}
You should try to use ObjectDataProvider
.
It will be something like this
...
<UserControl.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="AlignmentValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="HorizontalAlignment" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</UserControl.Resources>
<Border Margin="10" BorderBrush="Aqua"
BorderThickness="3" Padding="8">
<StackPanel Width="300">
<TextBlock>bla-bla</TextBlock>
<ListBox Name="myComboBox" SelectedIndex="0" Margin="8"
ItemsSource="{Binding Source={StaticResource AlignmentValues}}"/>
<Button Content="Click Me!"
HorizontalAlignment="{Binding ElementName=myComboBox,
Path=SelectedItem}"/>
</StackPanel>
</Border>
...
精彩评论