C# WPF/XAML-使用';风格';使用模型图元名称创建工具提示的步骤

C# WPF/XAML-使用';风格';使用模型图元名称创建工具提示的步骤,c#,wpf,xaml,dynamic,tooltip,C#,Wpf,Xaml,Dynamic,Tooltip,我们在WPF中有一份非常复杂的问卷,有100个对照组。控件组被放入UserControls中,以更好地组织节。基于各种因素,它们是可见/折叠的。由于供应商变更,本调查问卷每季度变更一次。我们将数据模型绑定到datacontext。模型属性名称与数据库列名匹配 当问卷转到QA时,他们想要一些简单的方法将问卷控件与数据库列关联起来。作为尽职调查的一部分,他们验证数据库中的值是否与他们在GUI中输入的值匹配 我的想法是添加一个工具提示(或类似的机制)来显示绑定属性。我们不希望最终用户看到这一点,因此需

我们在WPF中有一份非常复杂的问卷,有100个对照组。控件组被放入UserControls中,以更好地组织节。基于各种因素,它们是可见/折叠的。由于供应商变更,本调查问卷每季度变更一次。我们将数据模型绑定到datacontext。模型属性名称与数据库列名匹配

当问卷转到QA时,他们想要一些简单的方法将问卷控件与数据库列关联起来。作为尽职调查的一部分,他们验证数据库中的值是否与他们在GUI中输入的值匹配

我的想法是添加一个工具提示(或类似的机制)来显示绑定属性。我们不希望最终用户看到这一点,因此需要使用配置设置打开/关闭此动态工具提示

我试图找到一种简单的方法,在全球范围内使用反射。它将在所有控件上生成具有绑定属性名称的工具提示(通过配置选项启用/禁用)。我想也许我可以用一个转换器来做这件事,但我不知道该怎么做

我希望工具提示在控件上显示“VariableName1”或“VariableName2”(VariableName1/VariableName2是数据库列的名称)



我尝试了这样一种方法,认为在“QATooltips”方法中,我可以进行反射并构建工具提示。但转换器从未被调用。所以我有点不对劲

<UserControl.Resources>
    <local:QATooltips x:Key="QATooltips" />
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip Content="{Binding Converter={StaticResource QATooltips}}" />
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

您可以通过对相关元素调用
GetBindingExpression
来完成此操作,并传入您感兴趣的依赖项属性。该名称将位于结果表达式的
ResolvedSourcePropertyName
属性中

您正在寻找的转换器如下所示:

public class BindingConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value as FrameworkElement)?.GetBindingExpression(parameter as DependencyProperty)?.ResolvedSourcePropertyName;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
请注意,它期望您感兴趣的DP作为命令参数传入,这样您就不必为每个不同的绑定类型创建单独的转换器类型

回到XAML,您只需执行以下操作:

xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"

<Window.Resources>

    <local:BindingConverter x:Key="BindingConverter" />

    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip Content="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource BindingConverter}, ConverterParameter={x:Static controls:TextBlock.TextProperty}}"/>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type RadioButton}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip Content="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource BindingConverter}, ConverterParameter={x:Static controls:RadioButton.IsCheckedProperty}}"/>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>

<StackPanel Orientation="Vertical">
    <TextBlock Text="{Binding MyTextField}" />
    <RadioButton IsChecked="{Binding MyBooleanField}" Content="Click Me" />
</StackPanel>
xmlns:controls=“clr命名空间:System.Windows.controls;assembly=PresentationFramework”

(顺便说一句,您的原始代码不起作用的原因是工具提示不是其“父”控件可视化树的子元素,这就是为什么您必须通过PlacementTarget进行绑定)。

Wow。我能让它完全符合我的要求。非常感谢你!
public class BindingConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value as FrameworkElement)?.GetBindingExpression(parameter as DependencyProperty)?.ResolvedSourcePropertyName;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"

<Window.Resources>

    <local:BindingConverter x:Key="BindingConverter" />

    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip Content="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource BindingConverter}, ConverterParameter={x:Static controls:TextBlock.TextProperty}}"/>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type RadioButton}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip Content="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource BindingConverter}, ConverterParameter={x:Static controls:RadioButton.IsCheckedProperty}}"/>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>

<StackPanel Orientation="Vertical">
    <TextBlock Text="{Binding MyTextField}" />
    <RadioButton IsChecked="{Binding MyBooleanField}" Content="Click Me" />
</StackPanel>