如何从DataTemplate获取绑定名称

时间:2017-10-24 18:00:56

标签: c# wpf sorting listview mvvm

我试图通过它的标题对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>

所以我的问题是 - 我如何得到这个&#34; PVNum&#34;代码后面的字符串?

我确实试过这个,虽然s是空的 - 所以我想我已经离开了:

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

有什么建议吗?

2 个答案:

答案 0 :(得分: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中,您将附加属性设置为模板内Path中使用的Binding。基于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();
}

答案 1 :(得分:1)

应为Text Block .Text属性:

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