代码之家  ›  专栏  ›  技术社区  ›  Dave

将WPF组合框绑定到List<MyClass>,其中MyClass没有属性,只有方法

  •  0
  • Dave  · 技术社区  · 14 年前

    我想把一个组合框绑定到一个设备列表,列表。我用,

    m_ctrlCB.DataContext = m_List;
    m_ctrlCB.DisplayMemberPath = "ToString()";
    m_ctrlCB.SelectedValuePath = "ToString()";  // do I even need this?
    

    我在设备中没有任何要绑定的属性,而且它不是我的类。但是,它们确实重写了ToString,使其适合显示在combobox中(例如:“Class Device。数字1”。

    我想我也很乐意创建ComboBoxItems,并在必要时将它们添加到ComboBox中。但是如果我走这条路,我该如何设置显示内容和实际对象本身,以便在用户从组合框中选择它时获得它?

    设备#1 设备#2 我该怎么做?

    谢谢, 戴夫

    3 回复  |  直到 14 年前
        1
  •  3
  •   ASanch    14 年前

    您不必设置DisplayMemberPath和SelectedValuePath。由于设备对象重写ToString(),因此它应该自己显示正确的字符串。

    编辑:

    要回答您的“奖金问题”,一种方法是使用调用您感兴趣的方法的IValueConverter。下面的示例代码演示了这一点。这里有一个组合框,它的项由TextBlock(它显示ToString()方法的值)和一个按钮(它显示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
    }
    
        2
  •  1
  •   Zach Johnson    14 年前

    一种方法是创建一个包装器类并提供相应的属性。例如:

    class DeviceWrapper
    {
        private Device device;
    
        public DeviceWrapper(Device device)
        {
            this.device = device;
        }
    
        public int DeviceNumber
        {
            return this.device.GetDeviceNumber();
        }
    
        // etc...
    }
    
        3
  •  1
  •   madcyree    14 年前

    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>
    ...
    
    推荐文章