Привязка WPF ComboBox к списку <MyClass>, где MyClass не имеет свойств, только методы - PullRequest
0 голосов
/ 21 сентября 2010

Я хочу связать комбинированное окно со списком Устройство, Список. Я использую,

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

У меня нет свойств в Device для привязки, и это не мой класс. Однако они переопределяют ToString на то, что подходит для отображения в выпадающем списке (что-то вроде: «Class Device. Number 1».

Однако то, что я написал, не работает. То, что я вижу в выпадающем списке, это пустые элементы. Мое событие selectionChanged работает И e.AddedItems [0] действительно является устройством, поэтому я близок. Как я могу получить что-то значимое для отображения в поле со списком.

Полагаю, я также был бы рад создать ComboBoxItems и добавить их в ComboBox, если это необходимо. Но если я пойду по этому пути, как мне настроить отображение и сам объект, чтобы я мог получить его, когда пользователь выберет его из выпадающего списка?

Бонусный вопрос. Если вместо использования ToString я хочу использовать GetDeviceNumber () и объединить его с моим собственным тестом, чтобы пользователь увидел, Устройство № 1 Устройство № 2 как бы я это сделал?

спасибо, Dave

Ответы [ 3 ]

3 голосов
/ 21 сентября 2010

Вам не нужно устанавливать DisplayMemberPath и SelectedValuePath.Поскольку ваш объект Device переопределяет ToString (), он должен отображать правильную строку самостоятельно.

EDIT:

Чтобы ответить на ваш "бонусный вопрос", один из способовсделать это, чтобы использовать 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 голос
/ 21 сентября 2010

Вы должны попытаться использовать 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>
...
1 голос
/ 21 сентября 2010

Один из способов сделать это - создать класс-оболочку и предоставить ему соответствующие свойства. Например:

class DeviceWrapper
{
    private Device device;

    public DeviceWrapper(Device device)
    {
        this.device = device;
    }

    public int DeviceNumber
    {
        return this.device.GetDeviceNumber();
    }

    // etc...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...