我正在使用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不再被调用,因此背景保持红色。
在设置此控件的绑定后,任何人都知道如何调用触发器?或者任何其他建议,我可能会以错误的方式解决问题。
谢谢!
答案 0 :(得分:1)
发生这种情况的原因是,Binding
不会再次作为源调用,即TextBox
本身在创建后永远不会更改!
假设您专注于TextBox
。
将Container的Tag属性(Window
/ UserControl
)设置为当前控件。
myWindow.Tag = FocusManager.GetFocusedElement(myWindow);
使用此Binding
更改触发器。
<DataTrigger
Binding="{Binding,
Path=Tag,
RelativeSource={RelativeSource AncestorType=Window},
Converter={StaticResource HasBindingConv}}" .. >
刷新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
,似乎无法做到这一点。希望有人发现它有用