Атрибут привязки условия не работает? - PullRequest
20 голосов
/ 10 августа 2009

Я уже давно борюсь с этим кодом и не могу найти полных ответов на мой вопрос. Я создал небольшой пример для иллюстрации проблемы:

<ListView >
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
        <StackPanel Margin="0,0,20,0" IsItemsHost="True" />
    </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.Items>
        <TextBlock>Test1</TextBlock>
        <TextBlock>Test2</TextBlock>
        <TextBlock>Test3</TextBlock>
        <TextBlock>Test4</TextBlock>
        <TextBlock>Test5</TextBlock>
    </ListView.Items>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Grid>
                        <ContentPresenter/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                 <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" />
                                 <Condition Property="IsSelected" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Visibility" Value="Collapsed"/>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
         </Style>
     </ListView.ItemContainerStyle>
 </ListView>

В соответствии с настройками MultiTrigger, выбранный элемент должен появиться снова, когда мышь больше не находится над выбранным элементом. Этот код, однако, создает исключение InvalidOperationException с сообщением «Должно иметь ненулевое значение для свойства». Если вы удалите Условие, использующее атрибут «Связывание», исключение не будет выдано. В документации MSDN указано, что у вас должен быть установлен атрибут Property или Binding. Приведенный выше код функции, такие как атрибут Binding, не установлены. Фактически, во всех моих тестовых случаях не имеет значения, какой атрибут Binding установлен; исключение все еще выброшено. Есть мысли?

Ответы [ 2 ]

52 голосов
/ 11 августа 2009

Это один из тех случаев, когда вам приходится смириться с этим и признать, что вы совершили ошибку. Однако, чтобы спасти еще одну несчастливую душу от той же участи, я открою свое прозрение.

Во-первых, если бы я прочитал всю документации, я бы прочел ту часть, в которой говорилось, что если вы используете атрибут «Binding» условия, его необходимо включить в элемент MultiDataTrigger (вместо элемента MutiTrigger в моем опубликованном примере).

Во-вторых, после внесения этих изменений элемент MultiTrigger заменяется следующим кодом:

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" />
        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/>
    </MultiDataTrigger.Conditions>
    <Setter Property="Visibility" Value="Collapsed"/>
</MultiDataTrigger>

Теперь пример работает, но поскольку выбранный элемент свернут, условие триггера переключается назад и вперед, заставляя выбранный элемент мерцать и исчезать из поля зрения. Имеет смысл, но по общему признанию не то, что я намеревался.

В любом случае, надеюсь, что это поможет кому-то совершить ту же самую ошибку с головой!

3 голосов
/ 02 августа 2010

На очень похожей заметке, вытягивая IsMouseOver из границы в качестве основного содержимого шаблона данных, и вытягивая IsSelected от Ancestor. Интересно, что оба условия должны иметь относительный путь, я бы предположил, что путь по умолчанию будет локальный текстовый текст. Спасибо за вышеуказанное решение.

Сломанный код

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
                   Value="True" />
        <Condition SourceName="Border"
                   Property="IsMouseOver"
                   Value="True" />
    </MultiDataTrigger.Conditions>
    <Setter TargetName="Border"
            Property="Background"
            Value="{StaticResource OnBrushSelected}" />
</MultiDataTrigger>

Рабочий код

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}, Path=IsMouseOver}"
                   Value="True" />
        <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
                   Value="True" />
    </MultiDataTrigger.Conditions>
    <Setter TargetName="Border"
            Property="Background"
            Value="{StaticResource OnBrushSelected}" />
</MultiDataTrigger>
...