WPF Style DataTrigger基于DependencyProperty绑定

时间:2012-10-25 11:50:40

标签: wpf binding styles datatrigger

我正在使用WPF表单设计器,您可以将Labels,TextBox,ComboBox等控件拖放到设计图面,然后通过Property Grid用户可以为每个控件设置数据绑定。我要求为那些没有给定属性的Binding集的控件显示红色背景。

我最初的想法是创建一个HasBindingConverter,它将接受调用元素本身并检查它是否具有绑定到某个属性。在这种情况下TextBox.TextProperty

public class HasBindingConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        FrameworkElement fe = value as FrameworkElement;
        if(fe != null)
        {
            Binding binding = BindingOperations.GetBinding(fe, TextBox.TextProperty);
            return binding != null;
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

然后我将一个与TextBox控件类型相关联的Style添加到我的表单的Resources部分,这是一个UserControl:

<UserControl.Resources>
    <Style TargetType="TextBox">
        <Style.Resources>
            <Converters:HasBindingConverter x:Key="HasBindingConv"/>
        </Style.Resources>
        <Style.Triggers>
            <DataTrigger
            Binding="{Binding,
            RelativeSource={RelativeSource Self},
            Converter={StaticResource HasBindingConv}}"
            Value="False">
                <Setter Property="TextBox.Background" Value="Red" />
                </DataTrigger>
 <DataTrigger Binding="{Binding 
            RelativeSource={RelativeSource Self},
            Converter={StaticResource HasBindingConv}}"
            Value="True">
                <Setter Property="TextBox.Background" Value="White" />
        </Style.Triggers>
    </Style>

因此,如果TextBox没有TextBox.TextProperty的数据绑定集,那么它会将其背景设置为红色。这部分工作正常,问题是当用户为此控件设置TextBox.TextProperty绑定时,我的Converter不再被调用,因此背景保持红色。

在设置此控件的绑定后,任何人都知道如何调用触发器?或者任何其他建议,我可能会以错误的方式解决问题。

谢谢!

2 个答案:

答案 0 :(得分:1)

发生这种情况的原因是,Binding不会再次作为源调用,即TextBox本身在创建后永远不会更改!

假设您专注于TextBox

  1. 将Container的Tag属性(Window / UserControl)设置为当前控件。

    myWindow.Tag = FocusManager.GetFocusedElement(myWindow);
    
  2. 使用此Binding更改触发器。

    <DataTrigger
        Binding="{Binding,
        Path=Tag,
        RelativeSource={RelativeSource AncestorType=Window},
        Converter={StaticResource HasBindingConv}}" .. >
    
  3. 刷新Tag的{​​{1}}属性。

    Window

答案 1 :(得分:0)

我找到了解决这个问题的另一种方法。

我创建了一个ControlHasBindingBehavior Attached属性,最初将其设置为false。

public class ControlHasBindingBehavior
{
    #region DependencyProperty HasBinding

    /// <summary>
    /// Registers a dependency property as backing store for the HasBinding property
    /// Very important to set default value to 'false'
    /// </summary>
    public static readonly DependencyProperty HasBindingProperty =
        DependencyProperty.RegisterAttached("HasBinding", typeof(bool), typeof(ControlHasBindingBehavior),
        new FrameworkPropertyMetadata(false,FrameworkPropertyMetadataOptions.AffectsRender));

    /// <summary>
    /// Gets or sets the HasBinding.
    /// </summary>
    /// <value>The HasBinding.</value>
    public static bool GetHasBinding(DependencyObject d)
    {
        return (bool)d.GetValue(HasBindingProperty);
    }

    public static void SetHasBinding(DependencyObject d, bool value)
    {
        d.SetValue(HasBindingProperty, value);
    }

    #endregion
}

然后在我的FormDesigner视图中,我为所有TextBox创建了一个样式和触发器,因此当Textbox'HasBinding'附加属性为false时,它会将背景变为红色:

        <Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Behaviors:ControlHasBindingBehavior.HasBinding" Value="False">
                <Setter Property="Background" Value="Red"/>
            </Trigger>
        </Style.Triggers>
    </Style>

最后,当User为给定控件成功设置绑定时,我将Attached Property设置为'True':

                ControlHasBindingBehavior.SetHasBinding(SelectedObject,true);

当发生这种情况时,我的TextBox.Background再次变为白色:) 最初我想以通用的方式将样式触发器应用于所有UIElements,FrameworkElements或Controls,但根据this thread

,似乎无法做到这一点。

希望有人发现它有用