将WPF ComboBox绑定到List <myclass>,其中MyClass没有属性,只是方法</myclass>

时间:2010-09-20 21:38:19

标签: wpf data-binding combobox

我想将一个组合框绑定到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 我该怎么做?

感谢, 戴夫

3 个答案:

答案 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>
...