是否可以通过数据绑定项来控制单个列表视图项的选定、指针悬停和按下状态

2024-03-30

我目前正在尝试设计一个ListView因此其中的每个项目都可以控制自己的背景颜色、PointerOver、Pressed 和 Selected 状态。

我发现我可以设置背景ListViewItem to Transparent并让DataTemplate对于我的项目控制背景。但我正在努力解决的是VisualStates of the ListViewItem。他们只是看起来风格不正确。

到目前为止我所尝试的是把我的Binding里面的颜色代码Style为了ListViewItem像这样:

注意:为了简洁起见,代码已被删减,ListViewItem取自 Generic.xaml 的样式

<Style TargetType="ListViewItem">
    <Setters.../>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListViewItem">
                <Grid x:Name="ContentBorder">
                    <!-- ContentPresenter etc in here -->
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Pressed">
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding AccentColour}" />
                                </ObjectAnimationUsingKeyFrames>
                            </VisualState>
                            <!-- More Visual States-->
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然而这不起作用,我认为这与ListViewItem不知道DataContext为了Binding.

我的项目只是一个基本类,用于保存与项目关联的文本以及背景和状态的颜色等信息。

public class BasicItem {
    // Constructor etc

    public SolidColorBrush AccentColour { get; set; }
    // More Colours
}

我考虑过的另一种方法是创建AttachedPropertiesListViewItem 上的颜色。唯一的问题是我不确定如何与它们绑定。

任何人都知道该项目是否有可能以这种方式控制其状态,任何帮助表示赞赏。


我考虑过的另一种方法是创建 AttachedProperties ListViewItem 上的颜色。唯一的问题是我不确定我会如何 与他们绑定。

你是对的使用附加属性这就是可以做到的。

Step 1。定义您的附加属性

public static Brush GetPointerOverBackground(DependencyObject obj)
{
    return (Brush)obj.GetValue(PointerOverBackgroundProperty);
}
public static void SetPointerOverBackground(DependencyObject obj, Brush value)
{
    obj.SetValue(PointerOverBackgroundProperty, value);
}
public static readonly DependencyProperty PointerOverBackgroundProperty =
    DependencyProperty.RegisterAttached("PointerOverBackground", typeof(Brush), typeof(YourStaticClass), new PropertyMetadata(null));

Step 2。为附加属性定义默认值

<Setter Property="local:YourStaticClass.PointerOverBackground" Value="LightBlue" />

Step 3。在您的视觉状态中使用附加属性

<VisualState x:Name="PointerOver">
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
        <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding local:YourStaticClass.PointerOverBackground}" />
    </ObjectAnimationUsingKeyFrames>
</VisualState>

Step 4。创建一个定义所有画笔的接口

这样做的原因是我们可以稍后转换该对象(即BasicItem) 绑定到每个模板界面,无需知道其具体类型。当然你的BasicItem应该实施这个界面.

public interface ISupportListViewItemBrushes
{
    SolidColorBrush PointerOverBrush { get; set; }

Step 5。创建一个Behavior负责分配Brushes to ListViewItems

这就是一切都聚集在一起的地方。首先我们需要安装XAML 行为 Nuget 包 https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Uwp.Managed/。之后,创建一个Behavior called SupportListViewItemBrushesBehavior并使其只能连接到ListView.

public class SupportListViewItemBrushesBehavior : Behavior<ListView>

ListView有一个名为ContainerContentChanging我们可以访问每个ListViewItem及其底层Item (i.e. BasicItem/ISupportListViewItemBrushes) 目的。最后,我们只需使用SetAttachedPropertyName方法来分配相应的Brush to the ListViewItem像下面这样

private void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    if (!args.InRecycleQueue && 
        args.ItemContainer is ListViewItem container && 
        args.Item is ISupportListViewItemBrushes brushes)
    {
        Helper.SetPointerOverBackground(container, brushes.PointerOverBrush);
    }
}

就这样!


请注意,我们必须创建Behavior这里因为UWP不支持FindAncestor尚未绑定。或者,不使用附加属性 and a Behavior,你可以扩展ListView/ListViewItem达到同样的结果。

我已经包含了一个小样本here https://github.com/JustinXinLiu/DynamicListViewItemColorsRepo供你参考。这是最终结果。希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以通过数据绑定项来控制单个列表视图项的选定、指针悬停和按下状态 的相关文章

随机推荐