C# WPF如何将附加属性绑定到依赖属性

C# WPF如何将附加属性绑定到依赖属性,c#,wpf,xaml,dependency-properties,attached-properties,C#,Wpf,Xaml,Dependency Properties,Attached Properties,我正在自定义DataGridCells,使其角落中有一个小三角形,并带有工具提示。仅当工具提示包含内容且工具提示的内容来自DataGrid的ItemsSource时,此三角形才应显示 角上有三角形的DataGrid: 现在我创建了一个名为Hint的附加属性,它将绑定到包含工具提示内容的ItemsSource的属性 public class HintAttachedProperty { public static void SetHint(DependencyObject ob

我正在自定义DataGridCells,使其角落中有一个小三角形,并带有工具提示。仅当工具提示包含内容且工具提示的内容来自DataGrid的ItemsSource时,此三角形才应显示

角上有三角形的DataGrid:

现在我创建了一个名为Hint的附加属性,它将绑定到包含工具提示内容的ItemsSource的属性

public class HintAttachedProperty
{

        public static void SetHint(DependencyObject obj, string text)
        {
            obj.SetValue(HintProperty, text);
        }

        public static string GetHint(DependencyObject obj)
        {
            return obj.GetValue(HintProperty)?.ToString() ?? string.Empty;
        }

        public static readonly DependencyProperty HintProperty =
            DependencyProperty.RegisterAttached("Hint", typeof(string), typeof(HintAttachedProperty), new FrameworkPropertyMetadata(null));

}
DataGrid的xaml,现在附加的属性提示设置为值“A test”:

调试时,我可以在转换器中看到值是如何“测试”的,因此不会隐藏三角形,但当我将光标放在工具提示上时,工具提示为空:

提示值:

工具提示为空:

另一方面,如果我直接绑定到样式中ItemsSource的属性,例如员工姓名,ToolTip=“{Binding EmployeeName}”它可以完美地工作:

如何将和附着的属性的值绑定到属性?这可能吗?也许我应该去另一个方向


感谢您的关注

转换器是冗余的,您只需更正绑定即可工作

Polygon
中,您需要找到
DataGridCell
祖先,而不是
Self
,因为那是多边形。您需要从那里访问
,因为这是
提示
所附加的内容

<Polygon x:Name="pol" ToolTip="{Binding Column.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}}" Grid.Column="1" HorizontalAlignment="Right" Points="5,0 10,0, 10,5" Stroke="Black" Fill="Black"/>

谢谢你的评论。在当前项的数据上下文或数据网格数据上下文上绑定属性不能以这种方式工作,因为该列不是可视化树的一部分,因为该列只是该列中单元格应如何构造的定义

我将向您展示当前项的数据上下文的解决方法。绑定到父级数据网格的数据上下文的工作方式不同。您可以通过
样式
提示
属性附加到单元格中实际显示的元素。在样式中,您可以访问当前项的数据上下文

如果有只读列,则只需创建
ElementStyle
。如果要在editbale列中显示多边形和工具提示,还需要一个
EditingElementStyle

<DataGridTextColumn Header="EmployeeName" Binding="{Binding EmployeeName}">
   <DataGridTextColumn.ElementStyle>
      <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
        <Setter Property="local:HintAttachedProperty.Hint" Value="{Binding EmployeeName}"/>
      </Style>
   </DataGridTextColumn.ElementStyle>
   <DataGridTextColumn.EditingElementStyle>
      <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
         <Setter Property="local:HintAttachedProperty.Hint" Value="{Binding EmployeeName}"/>
      </Style>
   </DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>

简单回顾一下,这里的主要问题是您无法从列访问数据上下文

覆盖单元格
ControlTemplate
的另一种方法是创建
DataGridTemplateColumn
s,在其中为每个列创建自定义
DataTemplate
,其中包含箭头多边形和工具提示


然后,您可以轻松地附加和绑定
Hint
属性,因为您可以访问当前项的所有控件和数据上下文。此解决方案的缺点是,您必须为每列创建自定义数据模板,并将箭头和工具提示XAML复制到所有位置。

您的设置者感谢您的回复!当直接设置附加属性的值时,这确实有效,但是如果我将其绑定到属性,则它不是本地的:hintatachedproperty.Hint=“{Binding EmployeeName}”@mmas我为您的场景添加了两种解决方法。谢谢!它确实有效,我正在寻找一种更通用的方法,不必为每个列创建自定义数据模板,但我会这样做
public class HintConverters : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
         DataGridCell dgc = value as DataGridCell;
         if (dgc != null)
         {
             DataGridColumn col = dgc.Column;
             if (col != null)
             {
                 var hint = HintAttachedProperty.GetHint(col);
                 return hint;
             }
         }
         return "";
     }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
<Polygon x:Name="pol" ToolTip="{Binding Column.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}}" Grid.Column="1" HorizontalAlignment="Right" Points="5,0 10,0, 10,5" Stroke="Black" Fill="Black"/>
<DataTrigger Binding="{Binding Column.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource Self}}" Value="{x:Static system:String.Empty}">
   <Setter TargetName="pol" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Column.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource Self}}" Value="{x:Null}">
   <Setter TargetName="pol" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataGridTextColumn Header="EmployeeName" Binding="{Binding EmployeeName}">
   <DataGridTextColumn.ElementStyle>
      <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
        <Setter Property="local:HintAttachedProperty.Hint" Value="{Binding EmployeeName}"/>
      </Style>
   </DataGridTextColumn.ElementStyle>
   <DataGridTextColumn.EditingElementStyle>
      <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
         <Setter Property="local:HintAttachedProperty.Hint" Value="{Binding EmployeeName}"/>
      </Style>
   </DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
<Polygon x:Name="pol" ToolTip="{Binding Content.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}}" Grid.Column="1" HorizontalAlignment="Right" Points="5,0 10,0, 10,5" Stroke="Black" Fill="Black" >
<DataTrigger Binding="{Binding Content.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource Self}}" Value="{x:Static system:String.Empty}">
   <Setter TargetName="pol" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content.(local:HintAttachedProperty.Hint), RelativeSource={RelativeSource Self}}" Value="{x:Null}">
   <Setter TargetName="pol" Property="Visibility" Value="Collapsed"/>
</DataTrigger>