繁体   English   中英

WPF - 使用 DisplayMemberBinding 将工具提示添加到 GridViewColumn

[英]WPF - Adding a Tooltip to a GridViewColumn with DisplayMemberBinding

我在需要DisplayMemberBindingGridViewColumn中有一个TextBlock TextBlock完全没有考虑,因为DisplayMemberBinding优先于CellTemplate 但是, Textblock有一个ToolTip ,我希望显示它特定于列本身。 我能够将大多数样式设置移到CellTemplate之外,因为它们对所有列都是通用的,但是ToolTip不能被带到外面,因为它需要绑定并且对于每列都是唯一的。

这是其中的一列。 由于DisplayMemberBinding优先, GridViewColumn.CellTemplate标记中的所有内容都可以删除。

            <GridViewColumn Header="Templates"
                            Width="200" 
                            DisplayMemberBinding="{Binding Path=Name}>
              <GridViewColumn.CellTemplate> 
                <DataTemplate DataType="{x:Type request:ModelDocument}">
                  <TextBlock ToolTip="{Binding Name}"/>
                </DataTemplate>
              </GridViewColumn.CellTemplate>
            </GridViewColumn>

我完成其他 Style 属性的方式如下。 这是在GridView之前完成的( GridViewListView的子项):

        <ListView.Resources>
          <Style TargetType="TextBlock">
            <Setter Property="TextTrimming" Value="CharacterEllipsis" />
            <Setter Property="TextWrapping" Value="NoWrap"/>
            <Setter Property="FontFamily" Value="Segue UI Light" />
            <Setter Property="FontSize" Value="13" />
          </Style>
        </ListView.Resources>

如何在不删除DisplayMemberBinding的情况下向每列添加唯一的ToolTip

正如@icebat 在评论中已经建议的那样, DataGrid更适合这种情况,为了澄清,这里有一个简单的演示实现:

   <DataGrid ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
    <DataGrid.Resources>
        <Style TargetType="TextBlock" x:Key="TbStyle">
            <Setter Property="TextTrimming" Value="CharacterEllipsis" />
            <Setter Property="TextWrapping" Value="NoWrap"/>
            <Setter Property="FontFamily" Value="Segue UI Light" />
            <Setter Property="FontSize" Value="13" />
        </Style>

    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTemplateColumn  Header="Templates" SortMemberPath="Name"
                         Width="200"  >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate >
                    <TextBlock Style="{StaticResource TbStyle}" ToolTip="{Binding Name}" Text="{Binding Name}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>

        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

尽管有更合适的解决方案,例如使用DataGrid而不是ListView ,但我想展示一个答案,让您可以在TextBlocks上使用ListViewDisplayMemberBindingToolTip完全按照您的意愿行事。

最后我有以下XAML:

<ListView ItemsSource="{Binding MyList}">
    <ListView.Resources>
        <local:GridRowPresenterToDataContextPropertiesConverter x:Key="GridRowPresenterToDataContextPropertiesConverter"></local:GridRowPresenterToDataContextPropertiesConverter>
        <Style TargetType="TextBlock">
            <Setter Property="TextTrimming" Value="CharacterEllipsis" />
            <Setter Property="TextWrapping" Value="NoWrap"/>
            <Setter Property="FontFamily" Value="Segue UI Light" />
            <Setter Property="FontSize" Value="13" />

            <!--THIS IS THE NEW PART-->

            <Setter Property="ToolTip">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource GridRowPresenterToDataContextPropertiesConverter}"
                                  ConverterParameter="Name, Value">
                        <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=GridViewRowPresenter}"/>
                        <Binding RelativeSource="{RelativeSource Mode=Self}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>

            <!--END OF THE NEW PART-->

        </Style>
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Templates" Width="200" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Templates" Width="200" DisplayMemberBinding="{Binding Value}"/>
        </GridView>
    </ListView.View>
</ListView>

我添加了一个简单的视图 model class 和另一个GridViewColumn用于测试目的:

public class MyViewModel {
    public string Name { get; set; } = "Hello.";
    public string Value { get; set; } = "world.";
}

此 XAML 将DataContextName属性设置为第一列中所有TextBlocksToolTip ,并将DataContextValue属性设置为第二列中所有TextBlocksToolTip 您可以通过添加到ConverterParameter="Name, Value"有序属性列表来处理其他列。

关键在于GridRowPresenterToDataContextPropertiesConverter的定义(这是我可能写过的最不直接和最老套的IMultiValueConverter之一):

public class GridRowPresenterToDataContextPropertiesConverter : IMultiValueConverter {
    public static T FindVisualSelfOrChildren<T>(DependencyObject parent) where T : DependencyObject {
        if (parent == null) return null;
        if (parent is T) return parent as T;
        IEnumerable<DependencyObject> children = Enumerable.Range(0, VisualTreeHelper.GetChildrenCount(parent)).Select(i => VisualTreeHelper.GetChild(parent, i));
        foreach (var child in children) {
            T result = FindVisualSelfOrChildren<T>(child);
            if (result != null) return result as T;
        }
        return null;
    }

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        var presenter = (GridViewRowPresenter)values[0];
        var targetElement = values[1] as FrameworkElement;
        var sourceProperties = ((string)parameter).Split(',');

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(presenter); i++) {
            var child = VisualTreeHelper.GetChild(presenter, i);
            if (FindVisualSelfOrChildren<TextBlock>(child) == targetElement) {
                var dataContext = targetElement.DataContext;
                return dataContext.GetType().GetProperty(sourceProperties[i].Trim()).GetValue(dataContext);
            }
        }
        return "";
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
}

该转换器获取目标元素(这里,它将是每个TextBlock ),找出GridView的哪一列是存在的,并从ConverterParameter中提取正确索引处的属性。

这个答案是为了好玩而不是在生产代码中使用,它需要一些更智能的代码来处理现在绝对不支持的列的重新排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM