附加属性未触发 IMultiValueConverter
Posted
技术标签:
【中文标题】附加属性未触发 IMultiValueConverter【英文标题】:Attached Property not triggering IMultiValueConverter 【发布时间】:2015-03-08 14:52:27 【问题描述】:下面是我的 DataGrid,它带有一些与弹出控件相关联的附加属性。 ComboBox 由枚举填充。
<DataGrid Name="GenericDataGrid"
helpers:SearchBehaviours.SearchValue="Binding ElementName=FindTextbox, Path=Text, UpdateSourceTrigger=PropertyChanged"
helpers:SearchBehaviours.IsFindPopupOpen="Binding ElementName=PopupFind, Path=IsOpen, UpdateSourceTrigger=PropertyChanged"
helpers:SearchBehaviours.SearchableItems="Binding ElementName=ComboSearchableItems, Path=SelectedValue, UpdateSourceTrigger=PropertyChanged" >
</DataGrid>
<Popup x:Name="PopupFind">
<TextBox x:Name="FindTextbox" />
<ComboBox x:Name="ComboSearchableItems"
ItemsSource="Binding Source=helpers:Enumeration x:Type helpers:SearchItems"
DisplayMemberPath="Description"
SelectedValue="x:Static helpers:SearchItems.AllItems"
SelectedValuePath="Value" />
</Popup>
这是处理行为的类:
class SearchBehaviours
// Using a DependencyProperty as the backing store for IsTextMatch. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsTextMatchProperty =
DependencyProperty.RegisterAttached("IsTextMatch", typeof(bool), typeof(SearchBehaviours), new UIPropertyMetadata(false));
public static bool GetIsTextMatch(DependencyObject obj)
return (bool)obj.GetValue(IsTextMatchProperty);
public static void SetIsTextMatch(DependencyObject obj, bool value)
obj.SetValue(IsTextMatchProperty, value);
public static readonly DependencyProperty SearchValueProperty =
DependencyProperty.RegisterAttached("SearchValue", typeof(string), typeof(SearchBehaviours), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.Inherits));
public static string GetSearchValue(DependencyObject obj)
return (string)obj.GetValue(SearchValueProperty);
public static void SetSearchValue(DependencyObject obj, string value)
obj.SetValue(SearchValueProperty, value);
public static readonly DependencyProperty IsFindPopupOpenProperty =
DependencyProperty.RegisterAttached("IsFindPopupOpen", typeof(bool), typeof(SearchBehaviours),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
public static bool GetIsFindPopupOpen(DependencyObject obj)
return (bool)obj.GetValue(IsFindPopupOpenProperty);
public static void SetIsFindPopupOpen(DependencyObject obj, bool value)
obj.SetValue(IsFindPopupOpenProperty, value);
public static readonly DependencyProperty SearchableItemsProperty =
DependencyProperty.RegisterAttached("SearchableItems", typeof(SearchItems), typeof(SearchBehaviours), new PropertyMetadata(SearchItems.AllItems));
public static SearchItems GetSearchableItems(DependencyObject obj)
return (SearchItems)obj.GetValue(SearchableItemsProperty);
public static void SetSearchableItems(DependencyObject obj, SearchItems value)
obj.SetValue(SearchableItemsProperty, value);
问题出在下面的 IMultiValueConverter
<Style TargetType="x:Type DataGridCell" x:Key="textCellStyle" >
<Setter Property="helpers:SearchBehaviours.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="StaticResource SearchValueConverter" FallbackValue="False">
<Binding Path="Content.Text" RelativeSource="RelativeSource Self" />
<Binding Path="(helpers:SearchBehaviours.SearchValue)" RelativeSource="RelativeSource Self" />
<Binding Path="(helpers:SearchBehaviours.IsFindPopupOpen)" RelativeSource="RelativeSource Self"/>
<Binding Path="(helpers:SearchBehaviours.SearchableItems)" RelativeSource="RelativeSource Self"/>
<Binding />
<Binding RelativeSource="x:Static RelativeSource.Self"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="helpers:SearchBehaviours.IsTextMatch" Value="True">
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
当弹出窗口打开和关闭时,它会触发 IMultiValueConverter。 它在文本框文本更改时触发。 但是,如果 ComboBox 中的 SelectedValue 发生更改,则不会触发。 下面是当前触发时输出的相当简单的转换器。
public class SearchValueConverter : IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
Console.WriteLine("Triggered");
return false;
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
return null;
[编辑]
public enum SearchItems
[Description("All Items")]
AllItems,
[Description("Selected Items")]
SelectedItems
[结束编辑]
有人可以解决问题吗?
【问题讨论】:
我在SearchBehaviours
类中看不到定义IsTextMatch
属性。我想是 bool 属性,但您的 SearchValueConverter
不会在 Convert
方法中返回任何值。它应该返回布尔值。由于这个原因,触发器永远不会引发。
嗨@user2250152,我已经添加了 IsTextMatch 属性,你的位置只是一个 bool 属性。还添加了返回值,那应该是一个错字。还添加了枚举,默认情况下,组合框设置为 AllItems,当我选择 SelectedItems 时,我希望转换器触发,但这不会发生。
您可以尝试在SetSearchableItems
方法上放置一个断点,以检查组合框选择更改时附加的属性设置器是否被触发。这至少会告诉您绑定是否有效。
【参考方案1】:
更改DataGridCell Style
代码如下:
<Style TargetType="x:Type DataGridCell">
<Setter Property="local:SearchBehaviours.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="StaticResource SearchValueConverter" FallbackValue="False">
<Binding Path="Content.Text" RelativeSource="RelativeSource Self" />
<Binding Path="(local:SearchBehaviours.SearchValue)" RelativeSource="RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid" />
<Binding Path="(local:SearchBehaviours.IsFindPopupOpen)" RelativeSource="RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid"/>
<Binding Path="(local:SearchBehaviours.SearchableItems)" RelativeSource="RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid"/>
<Binding />
<Binding RelativeSource="x:Static RelativeSource.Self"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="local:SearchBehaviours.IsTextMatch" Value="True">
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
您将 DataGridCell 的所有附加属性传递给未分配的 MultiBinding Converter。为了解决此问题,您必须将 DataGrid 的附加属性传递给 MultiBindingConverter。
UPDATE :
你也可以像这样使用ComboBox
:
<ComboBox x:Name="ComboSearchableItems"/>
& 像这样通过代码将 ItemSource 分配给它:
ComboSearchableItems.ItemsSource = Enum.GetValues(typeof(SearchItems));
如果您只想使用XAML
进行绑定,请参考this link
【讨论】:
谢谢你会试一试 嗨,Amol,这在一定程度上有效。不过我有几个问题。为什么前两个属性可以正常工作而第三个不能?另一件事是 DataGrid 是虚拟化的,并且行被回收,这意味着一个单元格放弃其祖先并引发错误: System.Windows.Data 警告:4:找不到与引用'RelativeSource FindAncestor,AncestorType ='System. Windows.Controls.DataGrid' 我的意思是说我也想保持回收。 因为弹出窗口不在您窗口的VisualTree
中。它没有任何父母。 Popup 本身是 TextBox 和 ComboBox 的父级。
它正在工作,因为您已将弹出窗口子属性绑定到附加属性。在您的情况下,附加属性是您用于获取弹出值的媒介。在这种情况下很好......【参考方案2】:
使用 WPF 检查器检查您绑定到控件的内容。
enter link description here
【讨论】:
以上是关于附加属性未触发 IMultiValueConverter的主要内容,如果未能解决你的问题,请参考以下文章
具有未在模型中定义的附加属性的 NSManagedObject 子类