【问题标题】:Any better way of adding number to ListView's ItemContainerStyle?将数字添加到 ListView 的 ItemContainerStyle 有更好的方法吗?
【发布时间】:2014-12-21 19:47:02
【问题描述】:

我正在尝试稍微扩展我的 ListView 的 ItemContainerStyle 并添加一个与属性绑定的 TextBlock。它应该显示 ListView.SelectedItems.Count

目前我有一个可行的解决方案,但我对它不满意(我怀疑有更简单的方法,可能更干净)。它是这样的:

<Style x:Key="MyItemStyle" TargetType="ListViewItem">
  <!--Some code-->     
  <Setter Property="Template">
    <Setter.Value>
       <ControlTemplate TargetType="ListViewItem">
         <!--Some code-->
         <TextBlock DataContext="{Binding ElementName=contentPresenter, Path=DataContext}" Text="{Binding Number}" Foreground="Red"/>

这个想法很简单 - 我将 DataContext 设置为与 contentPresenter 相同,这意味着如果我在我的 ItemClass 中有一个属性 号码我把Item.Number = myList.SelectedItems.Count;放在那里一切正常。

但是在这种风格中还有其他方法吗?我的 ItemClass 中没有其他属性?不知何故可能会扩展 ListViewListViewItem

【问题讨论】:

    标签: c# xaml listview win-universal-app


    【解决方案1】:

    最初我以为我可以使用ElementName 绑定来检索ListView,然后将TextBlockText 绑定到ListViewSelectedItems.Count。类似于以下内容 -

    <!-- this won't work -->
    <TextBlock Text="{Binding Path=SelectedItems, ElementName=myList, Converter="{StaticResource GetCountConverter}"}" />
    

    但是,与 SelectedItem 依赖属性不同,这不起作用,因为 SelectedItems 只是一个普通的只读属性。

    一种常见的解决方法是创建一个带有几个附加属性的静态帮助程序类。像这样 -

    public static class ListViewEx
    {
        public static int GetSelectedItemsCount(DependencyObject obj)
        {
            return (int)obj.GetValue(SelectedItemsCountProperty);
        }
    
        public static void SetSelectedItemsCount(DependencyObject obj, int value)
        {
            obj.SetValue(SelectedItemsCountProperty, value);
        }
    
        public static readonly DependencyProperty SelectedItemsCountProperty =
            DependencyProperty.RegisterAttached("SelectedItemsCount", typeof(int), typeof(ListViewEx), new PropertyMetadata(0));
    
        public static bool GetAttachListView(DependencyObject obj)
        {
            return (bool)obj.GetValue(AttachListViewProperty);
        }
    
        public static void SetAttachListView(DependencyObject obj, bool value)
        {
            obj.SetValue(AttachListViewProperty, value);
        }
    
        public static readonly DependencyProperty AttachListViewProperty =
            DependencyProperty.RegisterAttached("AttachListView", typeof(bool), typeof(ListViewEx), new PropertyMetadata(false, Callback));
    
        private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                var listView = d as ListView;
                if (listView == null) return;
    
                listView.SelectionChanged += (s, args) =>
                {
                    SetSelectedItemsCount(listView, listView.SelectedItems.Count);
                };
            }
        }
    

    基本上,我在这里创建了一个SelectedItemsCount 附加属性来利用数据绑定。每当触发SelectionChanged 时,代码会将附加属性更新为SelectedItemsCount,因此它们始终保持同步。

    然后在 xaml 中,您需要先将帮助程序附加到 ListView(以便检索 ListView 实例并订阅其 SelectionChanged 事件),

    <ListView x:Name="myList" local:ListViewEx.AttachListView="true" 
    

    最后,更新TextBlock xaml 中的绑定。

    <TextBlock Text="{Binding Path=(local:ListViewEx.SelectedItemsCount), ElementName=myList}" />
    

    【讨论】:

    • 感谢您的回答。我正在尝试您的示例,但我不确定是否可以在 Page.Resources 中使用它 - 由于 ElementName = myList.
    • 你是对的,我已经将你的代码放到了我的示例中,在那里我启用了 ItemClick,并且我搞砸了一些东西。现在工作。你知道如何摆脱这个 ElementName - 定义一种可以在许多页面中使用的样式吗?
    • 对不起,我不太明白。你的意思是你不想使用 ElementName 绑定?
    • 我昨天搜索了很多,我的结论和你的一样。我会在几天内不接受这个问题(也许会有其他想法)。谢谢你的帮助。
    • @Romasz 您可以编写一个附加属性,将可视化树上升到最近的ListView 并“绑定”到它。它不会非常可重用,但可能是您需要的?你可以做一些通用的东西,但这不会很容易,而且会有点矫枉过正。
    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2023-04-01
    • 2021-12-21
    • 1970-01-01
    • 2023-01-31
    • 2023-01-25
    相关资源
    最近更新 更多