我想将一个组合框绑定到Device,List列表。我用,
m_ctrlCB.DataContext = m_List;
m_ctrlCB.DisplayMemberPath = "ToString()";
m_ctrlCB.SelectedValuePath = "ToString()"; // do I even need this?
我在Device中没有任何属性可以绑定到它,而不是我的类。但是,它们会将ToString覆盖为适合在组合框中显示的内容(类似于:“类设备。数字1”。
但是,我写的不起作用。我在组合框中看到的是空白项目。我的selectionChanged事件确实有效,而e.AddedItems [0]确实是一个设备,所以我很接近。如何在combox框中显示有意义的内容。
我想我也很乐意创建ComboBoxItem并在必要时将它们添加到ComboBox。但是,如果我走这条路线,我如何设置显示内容和实际对象本身,以便当用户从组合框中选择它时我可以得到它?
奖金问题。如果不是使用ToString,我想使用GetDeviceNumber()并将其与我自己的测试结合起来,以便用户看到, 设备#1 设备#2 我该怎么做?
感谢, 戴夫
答案 0 :(得分:3)
您不必设置DisplayMemberPath和SelectedValuePath。由于您的Device对象会覆盖ToString(),因此它应该自己显示正确的字符串。
修改强>
要回答您的“红利问题”,一种方法是使用调用您感兴趣的方法的IValueConverter。下面的示例代码演示了这一点。我这里有一个组合框,其项目由TextBlock(显示ToString()方法的值)表示,以及一个Button(显示GetDeviceNumber()方法的值)。
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>
代码隐藏:
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
}
答案 1 :(得分:1)
你可以做的一种方法是创建一个包装类并在其上提供适当的属性。例如:
class DeviceWrapper
{
private Device device;
public DeviceWrapper(Device device)
{
this.device = device;
}
public int DeviceNumber
{
return this.device.GetDeviceNumber();
}
// etc...
}
答案 2 :(得分:1)
您应该尝试使用ObjectDataProvider
。
会是这样的
...
<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>
...