【问题标题】:How to get Binding name from DataTemplate如何从 DataTemplate 获取绑定名称
【发布时间】:2018-04-05 15:24:07
【问题描述】:

我正在尝试按标题对 ListView 进行排序。

我正在关注这个MSDN example,并给出了here 的交替 - 如果我要使用直接绑定,则此行有效:

GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
string sortString = ((Binding)headerClicked.Column.DisplayMemberBinding).Path.Path

但问题是我没有直接使用 DisplayMemberBinding="{Binding PVNum}" 绑定列,而是使用 CellTemplate:

<ListView.Resources>
    <DataTemplate x:Key="NumberTemplate">
        <TextBlock Text="{Binding PVNum}" TextAlignment="Center"  />
    </DataTemplate>
</ListView.Resources>

<ListView.View>
  <GridView AllowsColumnReorder="False">
     <GridView.Columns>
        <GridViewColumn Header=" " CellTemplate="{StaticResource NumberTemplate}"/>
      </GridView.Columns>
   </GridView>
</ListView.View>

所以我的问题是 - 我如何在后面的代码中获取这个“PVNum”字符串?

我确实尝试过,虽然 s 为空 - 所以我想我已经离开了:

 var t = headerClicked.Column.CellTemplate.LoadContent() as TextBlock;
 var s = t.GetBindingExpression(TextBox.TextProperty);

有什么建议吗?

【问题讨论】:

    标签: c# wpf sorting listview mvvm


    【解决方案1】:

    一种可能的解决方案是为GridViewColumn 定义一个附加属性:

    public class GridViewColumnAttachedProperties
    {
        public static readonly DependencyProperty SortPropertyNameProperty = DependencyProperty.RegisterAttached(
            "SortPropertyName", typeof(string), typeof(GridViewColumnAttachedProperties), new PropertyMetadata(default(string)));
    
        public static void SetSortPropertyName(DependencyObject element, string value)
        {
            element.SetValue(SortPropertyNameProperty, value);
        }
    
        public static string GetSortPropertyName(DependencyObject element)
        {
            return (string) element.GetValue(SortPropertyNameProperty);
        }
    }
    

    在 XAML 中,您将附加属性设置为模板内 Binding 中使用的 Path。基于来自 MSDN 网站的示例:

    <ListView x:Name='lv' Height="150" HorizontalAlignment="Center" VerticalAlignment="Center" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
        <ListView.Resources>
            <DataTemplate x:Key="YearTemplate">
                <TextBlock Text="{Binding Year}" TextAlignment="Center"  />
            </DataTemplate>
            <DataTemplate x:Key="MonthTemplate">
                <TextBlock Text="{Binding Month}" TextAlignment="Center"  />
            </DataTemplate>
            <DataTemplate x:Key="DayTemplate">
                <TextBlock Text="{Binding Day}" TextAlignment="Center"  />
            </DataTemplate>
        </ListView.Resources>
    
        <ListView.ItemsSource>
            <collections:ArrayList>
                <system:DateTime>1993/1/1 12:22:02</system:DateTime>
                <system:DateTime>1993/1/2 13:2:01</system:DateTime>
                <system:DateTime>1997/1/3 2:1:6</system:DateTime>
                <system:DateTime>1997/1/4 13:6:55</system:DateTime>
                <system:DateTime>1999/2/1 12:22:02</system:DateTime>
                <system:DateTime>1998/2/2 13:2:01</system:DateTime>
                <system:DateTime>2000/2/3 2:1:6</system:DateTime>
                <system:DateTime>2002/2/4 13:6:55</system:DateTime>
                <system:DateTime>2001/3/1 12:22:02</system:DateTime>
                <system:DateTime>2006/3/2 13:2:01</system:DateTime>
                <system:DateTime>2004/3/3 2:1:6</system:DateTime>
                <system:DateTime>2004/3/4 13:6:55</system:DateTime>
            </collections:ArrayList>
        </ListView.ItemsSource>
    
        <ListView.View>
            <GridView>
                <GridViewColumn CellTemplate="{StaticResource YearTemplate}" local:GridViewColumnAttachedProperties.SortPropertyName="Year" />
                <GridViewColumn CellTemplate="{StaticResource MonthTemplate}" local:GridViewColumnAttachedProperties.SortPropertyName="Month" />
                <GridViewColumn CellTemplate="{StaticResource DayTemplate}" local:GridViewColumnAttachedProperties.SortPropertyName="Day" />
            </GridView>
        </ListView.View>
    </ListView>
    

    Click 事件处理程序中,您可以使用string bindingName = headerClicked.Column.GetValue(GridViewColumnAttachedProperties.SortPropertyNameProperty) as string; 检索附加属性的值。基于 MSDN 示例:

    GridViewColumnHeader _lastHeaderClicked;
    ListSortDirection _lastDirection = ListSortDirection.Ascending;
    
    private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
    {
        GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
    
        if (headerClicked != null)
        {
            if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
            {
                ListSortDirection direction;
                if (!ReferenceEquals(headerClicked, _lastHeaderClicked))
                {
                    direction = ListSortDirection.Ascending;
                }
                else
                {
                    if (_lastDirection == ListSortDirection.Ascending)
                    {
                        direction = ListSortDirection.Descending;
                    }
                    else
                    {
                        direction = ListSortDirection.Ascending;
                    }
                }
    
                string bindingName = headerClicked.Column.GetValue(GridViewColumnAttachedProperties.SortPropertyNameProperty) as string;
                Sort(bindingName, direction);
    
                if (direction == ListSortDirection.Ascending)
                {
                    headerClicked.Column.HeaderTemplate = Resources["HeaderTemplateArrowUp"] as DataTemplate;
                }
                else
                {
                    headerClicked.Column.HeaderTemplate = Resources["HeaderTemplateArrowDown"] as DataTemplate;
                }
    
                // Remove arrow from previously sorted header  
                if (_lastHeaderClicked != null && !ReferenceEquals(_lastHeaderClicked, headerClicked))
                {
                    _lastHeaderClicked.Column.HeaderTemplate = null;
                }
    
                _lastHeaderClicked = headerClicked;
                _lastDirection = direction;
            }
        }
    }
    
    private void Sort(string sortBy, ListSortDirection direction)
    {
        ICollectionView dataView = CollectionViewSource.GetDefaultView(lv.ItemsSource);
    
        dataView.SortDescriptions.Clear();
        SortDescription sd = new SortDescription(sortBy, direction);
        dataView.SortDescriptions.Add(sd);
        dataView.Refresh();
    }
    

    【讨论】:

      【解决方案2】:

      应该是TextBlock.Text属性:

      var t = headerClicked.Column.CellTemplate.LoadContent() as TextBlock;
      var s = t.GetBindingExpression(TextBlock.TextProperty);
      string sourcePropertyName = s.ParentBinding.Path.Path;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        • 2023-04-05
        • 2011-09-11
        • 1970-01-01
        相关资源
        最近更新 更多