Подтвердить что ты не робот

Атрибут привязки условий не работает?

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

<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; исключение все еще бросается. Любые мысли?

4b9b3361

Ответ 1

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

Во-первых, если бы я прочитал всю документацию, я бы прочитал часть, в которой говорилось, что если вы используете условие "Связывание", оно должно быть включено в элемент 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>

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

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

Ответ 2

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

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

<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>