Привязка данных выделена для ComboBoxItems в WPF - PullRequest
1 голос
/ 10 октября 2011

Я хочу получить свойство ComboBoxItem.IsHighlighted в моей ViewModel. Я подумал, что могу установить стиль контейнера элемента и сделать триггер на основе этого свойства, но затем я застрял.

<ComboBox ItemsSource="{Binding StartChapters}" SelectedItem="{Binding SelectedStartChapter}">
    <ComboBox.ItemContainerStyle>
        <Style TargetType="ComboBoxItem">
            <Style.Triggers>
                <Trigger Property="IsHighlighted" Value="True">
                    <Setter ??? />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

Все примеры, которые я смог найти, были установка какого-либо другого свойства пользовательского интерфейса и не возвращение данных в текстовый текст.

Кто-нибудь знает, как это может быть достигнуто?

1 Ответ

1 голос
/ 10 октября 2011

В идеальном мире мы могли бы просто привязать свойство IsHighlighted в ComboBoxItem к свойству в нашей модели представления и установить Mode в OneWayToSource:

<ComboBoxItem IsHighlighted="{Binding MyViewModelBoolProperty}" />

Однако WPF не позволяет устанавливать любые привязки для свойств зависимостей только для чтения, даже если режим равен OneWayToSource (что говорит о нашем намерении никогда не обновлять свойство зависимостей, только его указанный источник ). Для этого существует проблема подключения:

http://connect.microsoft.com/VisualStudio/feedback/details/540833/onewaytosource-binding-from-a-readonly-dependency-property

В проблеме с подключением есть предложенное решение, которое может помочь вам. Используемый подход заключается в создании MultiBinding - Tag, причем одна из привязок относится к вашему свойству только для чтения, а другая привязка - к вашей модели представления. Затем предоставляется конвертер, который устанавливает ваше свойство ViewModel:

   <Grid>
        <Grid.Resources>
            <l:MyConverter x:Key="MyConverter" />
        </Grid.Resources>

        <ComboBox VerticalAlignment="Center">
            <ComboBoxItem Content="Content Placeholder One" />
            <ComboBoxItem Content="Content Placeholder Two" />
            <ComboBoxItem Content="Content Placeholder Three" />
            <ComboBox.ItemContainerStyle>
                <Style TargetType="{x:Type ComboBoxItem}">
                    <Setter Property="Tag">
                        <Setter.Value>
                            <MultiBinding Converter="{StaticResource MyConverter}">
                                <Binding RelativeSource="{RelativeSource Self}" Path="IsHighlighted" />
                                <Binding />
                            </MultiBinding>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>

и конвертер:

public class MyConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (values != null && values[0] is bool && values[1] is MyViewModel)
            {
                ((MyViewModel)values[1]).MyBoolProperty = (bool)values[0];
                return (bool)values[0];
            }

            return DependencyProperty.UnsetValue;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

Не самое лучшее решение, поскольку оно включает Tag и скрывает наши настоящие намерения, но оно эффективно. Надеюсь, это поможет!

...