Доступ к ComboBoxItem DisplayValue

У меня есть comboBox, который имеет ItemsSource список объектов. Таким образом, DisplayMemberPath устанавливается для определенного свойства объекта. Конечно, это означает, что правильное значение отображается в ComboBoxItem.

Моя проблема в том, что я хотел бы иметь возможность получить это значение, возвращаемое DisplayMemberPath в XAML, чтобы я мог связать его с чем-то другим. т.е. я хотел бы иметь свойство "DisplayText" на ComboBoxItem.

Конечно, у меня этого нет, поэтому кто-нибудь знает способ получить это значение, не обращаясь к шаблону ComboBoxItem в поисках ContentHost?

Если вы заинтересованы в моем конкретном использовании этого, я пытаюсь сделать это в стиле ComboBox:

....
<Setter Property="ItemContainerStyle">
   <Setter.Value>
      <Style>
        <Setter 
             Property="AutomationProperties.AutomationId" 
             Value="{Binding RelativeSource={RelativeSource Self}, Path=MagicPathForDisplayedText}"/>
....

Конечно Path=Content работает нормально, если вы просто привязываете свой ItemsSource к свойствам, но когда это Object с DisplayMemberPath, Content будет этим Object.

Спасибо за любую помощь или переосмысление проблемы.

3 ответа

Решение

Самый простой способ справиться с такими проблемами, как правило, это Attached Properties и Behaviors.

Вы можете создать два прикрепленных свойства DisplayMemberPath а также DisplayTextтогда вы связываете DisplayMemberPath к родителю ComboBoxDisplayMemberPath и в PropertyChangedCallback Вы устанавливаете собственную привязку с тем же путем для DisplayText, После этого у вас есть свойство, которое вы можете привязать к

<Style x:Key="ComboBoxStyle" TargetType="ComboBox">
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="ComboBoxItem">
                <Setter Property="behaviors:DisplayTextBehavior.DisplayMemberPath"
                        Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ComboBox}},
                                        Path=DisplayMemberPath}"/>
                <Setter Property="AutomationProperties.AutomationId"
                        Value="{Binding RelativeSource={RelativeSource Self},
                                        Path=(behaviors:DisplayTextBehavior.DisplayText)}"/>
            </Style>
        </Setter.Value>                    
    </Setter>
</Style>

DisplayTextBehavior

public class DisplayTextBehavior
{
    public static DependencyProperty DisplayMemberPathProperty =
        DependencyProperty.RegisterAttached("DisplayMemberPath",
                                            typeof(string),
                                            typeof(DisplayTextBehavior),
                                            new FrameworkPropertyMetadata("", DisplayMemberPathChanged));
    public static string GetDisplayMemberPath(DependencyObject obj)
    {
        return (string)obj.GetValue(DisplayMemberPathProperty);
    }
    public static void SetDisplayMemberPath(DependencyObject obj, string value)
    {
        obj.SetValue(DisplayMemberPathProperty, value);
    }

    private static void DisplayMemberPathChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        ComboBoxItem comboBoxItem = sender as ComboBoxItem;
        string displayMemberPath = GetDisplayMemberPath(comboBoxItem);
        comboBoxItem.SetBinding(DisplayTextProperty, new Binding(displayMemberPath));
    }

    public static DependencyProperty DisplayTextProperty =
        DependencyProperty.RegisterAttached("DisplayText",
                                            typeof(string),
                                            typeof(DisplayTextBehavior),
                                            new FrameworkPropertyMetadata(""));
    public static string GetDisplayText(DependencyObject obj)
    {
        return (string)obj.GetValue(DisplayTextProperty);
    }
    public static void SetDisplayText(DependencyObject obj, string value)
    {
        obj.SetValue(DisplayTextProperty, value);
    }
}

Вы используете SelectedValuePath? Если нет, вы можете установить его так же, как DisplayMemberPath, и тогда выбранное значение будет доступно как SelectedValue.

Вы можете привязать промежуточный объект в ViewModel к SelectedItem собственность на Combobox. Затем также привяжите другой элемент отображения к этому промежуточному объекту. Тогда когда PropertyChanged событие запускается при выборе элемента, дисплей также обновляется через цепочку событий.

Другие вопросы по тегам