是否可以选择单个列表视图,指针和按下状态由数据绑定项控制

时间:2017-08-09 20:09:24

标签: c# xaml uwp uwp-xaml

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

我已经发现我可以将ListViewItem的背景设置为Transparent,让我的项目的DataTemplate控制背景。但我正在努力的是VisualStates的{​​{1}}。他们似乎没有正确的风格。

到目前为止,我尝试过的是将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的{​​{1}}有关。

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

Binding

我考虑过的另一种方法是为ListViewItem上的Colors创建public class BasicItem { // Constructor etc public SolidColorBrush AccentColour { get; set; } // More Colours } 。唯一的问题是我不确定如何与他们绑定。

任何人都知道物品是否有可能以这种方式控制其状态,任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:2)

  

我考虑的另一种方法是为其创建AttachedProperties   ListViewItem上的颜色。唯一的问题是我不确定我会怎么做   绑定他们。

您使用 AttachedProperties 是正确的,这就是它的完成方式。

步骤 1 。定义附加属性

handleButtonClick

步骤 2 。定义附加属性的默认值

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

步骤 3 。在Visual状态中使用附加属性

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

步骤 4 。创建一个定义所有画笔的界面

这样做的原因是我们以后可以将绑定到每个模板的对象(即<VisualState x:Name="PointerOver"> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding local:YourStaticClass.PointerOverBackground}" /> </ObjectAnimationUsingKeyFrames> </VisualState> )强制转换为此接口,而无需了解其具体类型。当然,您的BasicItem应该实现此接口

BasicItem

步骤 5 。创建public interface ISupportListViewItemBrushes { SolidColorBrush PointerOverBrush { get; set; } 负责将Behavior es分配给Brush s

这是一切都在一起的地方。首先,我们需要安装XAML Behavior Nuget Package。之后,创建名为ListViewItem的{​​{1}},并使其仅可附加到Behavior

SupportListViewItemBrushesBehavior

ListView有一个名为public class SupportListViewItemBrushesBehavior : Behavior<ListView> 的活动,我们可以访问每个ListView及其基础ContainerContentChanging(即ListViewItem / Item)宾语。最后,我们只使用BasicItem方法将相应的ISupportListViewItemBrushes分配给SetAttachedPropertyName,如下所示

Brush

这就是全部!

请注意,我们必须在此处创建ListViewItem,因为UWP尚未支持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 / FindAncestor而不是使用附加属性Behavior来实现相同的结果。

我添加了一个小样本here供您参考。这是最终结果。希望这有帮助!

enter image description here

答案 1 :(得分:0)

实现一个StyleSelector,为给定的项目选择所需的ListViewItem样式,并在ListView上将其设置为ItemContainerStyleSelector