为什么我的自定义ListViewItem没有正确更新?

问题描述 投票:0回答:1

我创建了两个继承自 ListView 和 ListViewItem 的自定义类。我创建这些类是因为我希望我的 ListView 具有正常的选择功能,但也希望它对于当前处于“活动”状态的项目具有不同颜色的 ListViewItem。双击可以激活 ListViewItem。

我的问题是我的属性“IsActive”在双击时按预期更新为 true 或 false,但颜色不会更改为样式中设置的触发器。我添加了一个名为“OnDependencyPropertyChanged”的方法来检查它是否正在注册属性,但这也没有改变。

我想知道为什么这个特定的解决方案不起作用,但我显然也愿意采用更简单的方法,因为这似乎有点不必要。

MainWindow.xaml.cs:

namespace TestProject
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<Person> People { get; set; } = new() 
        { 
            new Person("Jimbo", "Stevens", 54), 
            new Person("Hannah", "Johnston", 23), 
            new Person("Seamus", "O'Halligan", 19) 
        };

        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }

        public Person(string firstName, string lastName, int age)
        {
            FirstName = firstName;
            LastName = lastName;
            Age = age;
        }
    }
}

MainWindow.xaml:

<Window x:Class="TestProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestProject"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800"
        DataContext="{Binding RelativeSource={RelativeSource self}}">

    <Window.Resources>
        <Color x:Key="ControlLightColor">#F1F1F1</Color>
        <SolidColorBrush x:Key="ControlLightBrush"
                         Color="{DynamicResource ControlLightColor}" />
        <Color x:Key="ControlMediumColor">#999897</Color>
        <SolidColorBrush x:Key="ControlMediumBrush"
                         Color="{DynamicResource ControlMediumColor}" />

        <Color x:Key="BorderLightColor">#FFCCCCCC</Color>

        <Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
        <Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
        <Color x:Key="ActiveBackgroundColor">#a6f59f</Color>

        <Style  x:Key="LayersListViewItemStyle"
                TargetType="local:DoubleClickSetListViewItem">
            <Setter Property="SnapsToDevicePixels"
                    Value="true" />
            <Setter Property="OverridesDefaultStyle"
                    Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:DoubleClickSetListViewItem">
                        <Border x:Name="Border"
                                SnapsToDevicePixels="true"
                                Background="Transparent">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver" />
                                    <VisualState x:Name="Disabled" />
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Deactivated" />
                                    <VisualState x:Name="Activated">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                                          Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                <EasingColorKeyFrame KeyTime="0"
                                                                     Value="{DynamicResource ActiveBackgroundColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unselected" />
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                                          Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                <EasingColorKeyFrame KeyTime="0"
                                                                     Value="{DynamicResource SelectedBackgroundColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedUnfocused">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                                          Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                <EasingColorKeyFrame KeyTime="0"
                                                                     Value="{DynamicResource SelectedUnfocusedColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="LayersListViewStyle"
               TargetType="local:DoubleClickSetListView">
            <Setter Property="SnapsToDevicePixels"
                    Value="true" />
            <Setter Property="OverridesDefaultStyle"
                    Value="true" />
            <Setter Property="Foreground"
                    Value="Black" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListView">
                        <Border Name="Border"
                                BorderThickness="1"
                                Background="{DynamicResource ControlLightBrush}"
                                BorderBrush="{DynamicResource ControlMediumBrush}">
                            <ScrollViewer Margin="1">
                                <ItemsPresenter />
                            </ScrollViewer>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsGrouping"
                                     Value="true">
                                <Setter Property="ScrollViewer.CanContentScroll"
                                        Value="false" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    
    <Grid>
        <local:DoubleClickSetListView ItemsSource="{Binding People}"
                                      Style="{StaticResource LayersListViewStyle}">
            <local:DoubleClickSetListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=FirstName}"
                                    Header="First Name" />
                    <GridViewColumn DisplayMemberBinding="{Binding Path=LastName}"
                                    Header="Last Name" />
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Age}"
                                    Header="Age" />
                </GridView>
            </local:DoubleClickSetListView.View>
        </local:DoubleClickSetListView>
    </Grid>
</Window>

自定义ListView和ListViewItem:

namespace TestProject
{
    public class DoubleClickSetListView : ListView
    {
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is DoubleClickSetListViewItem;
        }
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new DoubleClickSetListViewItem();
        }
    }
    public class DoubleClickSetListViewItem : ListViewItem
    {
        public bool IsActive { get; set; } = false;

        public static readonly DependencyProperty IsActiveProperty =
       DependencyProperty.Register(
           "IsActive",
           typeof(bool),
           typeof(DoubleClickSetListViewItem),
           new PropertyMetadata(default(bool), OnDependencyPropertyChanged));

        protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
        {
            if (IsActive)
            {
                IsActive = false;
            }
            else
            {
                IsActive = true;
            }
        }
        private static void OnDependencyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }
    }
}

c# wpf
1个回答
0
投票

正确的创建方式是这样的

DependencyProperty

public bool IsActive
{
    get { return (bool)GetValue(IsActiveProperty); }
    set { SetValue(IsActiveProperty, value); }
}

public static readonly DependencyProperty IsActiveProperty =
    DependencyProperty.Register("IsActive", typeof(bool), typeof(ownerclass), new PropertyMetadata(default(bool), OnDependencyPropertyChanged)));

如您所见,

IsActive
属性也不用于存储值,而只是用于访问 DependencyProperty
GetValue
SetValue

作为提示,Visual Studio 中有一个用于创建 DependencyProperties 的片段,即

propdp

© www.soinside.com 2019 - 2024. All rights reserved.