Как привязать элемент представления в виде дерева к свойству IsSelectionActive - PullRequest
0 голосов
/ 04 августа 2020

У меня есть приложение WPF, в котором модели представлений находятся в. Net стандартной библиотеке, поэтому их можно повторно использовать в мобильных приложениях. Это означает, что модели представления не имеют доступа к фактическим элементам управления. У меня есть представление в виде дерева, которое использует DataTemplate для определения элемента представления в виде дерева. Затем у меня есть ContentControl, который отображает векторное изображение. Заливка векторного изображения - это данные, привязанные к модели представления. Проблема в том, что мне нужно изменить цвета, когда элемент древовидного представления больше не сфокусирован, но все еще выбран. Как можно привязать данные моей модели представления к свойству, ориентированному на элемент древовидного представления? После дополнительных исследований мне кажется, что мне нужно привязать элемент управления к моей модели просмотра одним способом к IsSelectionActive, однако стиль TreeViewItem не разрешает привязку к IsSelectionActive, заявляя, что нет установщика.

<DataTemplate x:Key="NormalTemplate">
   <StackPanel 
      Orientation="Horizontal" 
      ToolTip="{Binding Tooltip}"
      Opacity="{Binding Opacity}">

      <ContentControl Template="{StaticResource TreeViewItemImage}" Focusable="False"/>

      <fa:ImageAwesome  
         Style="{StaticResource TreeNodeIsWaitingForResult}"
         Visibility="{Binding IsRunning, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Hidden}"/>

      <TextBlock Text="{Binding Text}" Style="{StaticResource TreeViewItemTextBlockStyle}" />

      <StackPanel.ContextMenu>
         <ContextMenu                                 
            ItemContainerStyle="{StaticResource ContextMenuItemStyle}" 
            ItemsSource="{Binding MenuItemVMs}" 
            Visibility="{Binding MenuItemVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Hidden}"/>
      </StackPanel.ContextMenu>
   </StackPanel>
</DataTemplate>

Я сделал следующее изменяется для каждого комментария, но появляется следующая ошибка при попытке загрузить стиль ресурса векторного изображения:

System. Windows .Markup.XamlParseException: 'Привязка' не может быть установлена ​​для свойства 'Свойство' типа 'Курок'. «Привязка» может быть установлена ​​только в DependencyProperty объекта DependencyObject. '

Вот мой обновленный стиль:

    <Style x:Key="HostsTreeNodeStyle" TargetType="{x:Type ContentControl}" BasedOn="{StaticResource TreeNodeStyle}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                <Viewbox Style="{StaticResource TreeNodeViewboxStyle}">
                    <Canvas Width="24" Height="24">
                        <Path Data="M4,1H20A1,1 0 0,1 21,2V6A1,1 0 0,1 20,7H4A1,1 0 0,1 3,6V2A1,1 0 0,1 4,1M4,9H20A1,1 0 0,1 21,10V14A1,1 0 0,1 20,15H4A1,1 0 0,1 3,14V10A1,1 0 0,1 4,9M4,17H20A1,1 0 0,1 21,18V22A1,1 0 0,1 20,23H4A1,1 0 0,1 3,22V18A1,1 0 0,1 4,17M9,5H10V3H9V5M9,13H10V11H9V13M9,21H10V19H9V21M5,3V5H7V3H5M5,11V13H7V11H5M5,19V21H7V19H5Z" />
                    </Canvas>
                </Viewbox>
                <ControlTemplate.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="True"/>
                            <Condition Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="False"/>
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Foreground" Value="{Binding Color1}"/>
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="True"/>
                            <Condition Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="True"/>
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Foreground" Value="{Binding Color2}"/>
                    </MultiDataTrigger>
                    <Trigger Property="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="false">
                        <Setter Property="Foreground" Value="{Binding Color3}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

1 Ответ

0 голосов
/ 04 августа 2020

Вы можете использовать TreeViewItem.IsSelected и UIElement.IsKeyboardFocusWithin, чтобы создать MultiDataTrigger для этих условий.

Вот пример, который использует этот подход для изменения Text из TextBlock, если он находится внутри TreeViewItem, который выбран, но не в фокусе:

public partial class MainWindow : Window
{
    public List<FooItem> Items { get; } = new List<FooItem> { new FooItem() { Name = "A" },
                                                              new FooItem() { Name = "B" },
                                                              new FooItem() { Name = "C" },
                                                              new FooItem() { Name = "D" }};
}

public class FooItem
{
    public string Name { get; set; }

    public string SelectedButNotFocusedName => Name + "*";
}
<Window x:Class="CSharpTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <DockPanel>
        <TreeView ItemsSource="{Binding Items}" DockPanel.Dock="Left">
            <TreeView.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Setter Property="Text" Value="{Binding Name}"/>

                                <Style.Triggers>
                                    <MultiDataTrigger>
                                        <MultiDataTrigger.Conditions>
                                            <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="True"/>
                                            <Condition Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="False"/>
                                        </MultiDataTrigger.Conditions>

                                        <Setter Property="Text" Value="{Binding SelectedButNotFocusedName}"/>
                                    </MultiDataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

        <TextBox/>
    </DockPanel>
</Window>

TextBox в конце присутствует только в качестве другого элемент, на который вы можете сфокусироваться, чтобы убедиться, что код работает.

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

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