我有一个突出显示机制,可根据搜索的模式更改DataGridCell的背景。
<Setter Property="converters:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content.Text"/>
<Binding RelativeSource="{RelativeSource Self}" Path="(converters:DataGridTextSearch.SearchValue)" />
<Binding RelativeSource="{RelativeSource Self}" Path="Column.Header" />
</MultiBinding>
</Setter.Value>
</Setter>
触发器定义为:
<Style.Triggers>
<Trigger Property="converters:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="LightGray" />
</Trigger>
</Style.Triggers>
AttachedProperty的代码:
// 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(DataGridTextSearch), 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);
}
我想计算IsTextMatch为true的所有单元格。我还需要计算行数,一行上可能有很多单元格,所以我必须检测到这一点,但我正在尝试逐步进行。
我试图在我的静态类中添加另一个附加属性,它将计算多少&#34; true&#34;已设定。我从IsTextMatchProperty的PropertyChangedCallback更新了它的值,但它没有用。
这是访问该属性的XAML:
converters:DataGridTextSearch.CellsCount="{Binding RelativeSource={RelativeSource Self}, Path=Tag, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
其中DataGridTextSearch是属性所在的静态类。
还有其他方法吗?如果没有,我在这里做错了什么?
答案 0 :(得分:1)
基本方法是创建一个监督对象,比如Counter,它负责计算突出显示的单元格。
public class Counter : INotifyPropertyChanged
{
HashSet<DependencyObject> _hash = new HashSet<DependencyObject>();
public void Add(DependencyObject obj)
{
this._hash.Add(obj);
this.RaisePropertyChanged("Count");
}
public void Remove(DependencyObject obj)
{
this._hash.Remove(obj);
this.RaisePropertyChanged("Count");
}
public int Count
{
get
{
return this._hash.Count;
}
}
// INotifyPropertyChanged implementation omitted...
}
将附加的依赖项属性CellCounter添加到您的行为中:
// get/set methods omitted
public static readonly DependencyProperty CounterProperty = DependencyProperty.RegisterAttached(
"CellsCounter",
typeof(Counter),
typeof(GridBehavior),
new FrameworkPropertyMetadata(GridBehavior.OnCellsCounterPropertyChanged));
private static void OnCellsCounterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var oldCounter = e.OldValue as Counter;
if (oldCounter != null)
{
oldCounter.Remove(d);
}
var newCounter = e.NewValue as Counter;
if (newCounter != null)
{
var isSelected = GridBehavior.GetIsSelected(d);
if (isSelected)
{
newCounter.Add(d);
}
}
}
将计数器递增/递减的逻辑添加到IsTextMatch属性:
// get/set methods omitted
public static readonly DependencyProperty IsTextMatchProperty =
DependencyProperty.RegisterAttached(
"IsTextMatch",
typeof(bool),
typeof(GridBehavior),
new FrameworkPropertyMetadata(GridBehavior.OnIsTextMatchPropertyChanged));
private static void OnIsTextMatchPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var counter = d.GetValue(GridBehavior.CellsCounterProperty) as Counter;
if (counter == null)
{
return;
}
if ((bool)e.NewValue)
{
counter.Add(d);
}
else
{
counter.Remove(d);
}
}
然后在窗口/控件的“资源”部分中定义单个计数器,并在任何位置轮询Count属性。由于计数器的INotifyPropertyChanged性质,所有更改都将自动发送给计数器的消费者。像这样(我使用ListBox而不是DataGrid并且为了简单而没有使用视图模型但是没关系):
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:WpfApplication3">
<Window.Resources>
<view:Counter x:Key="CounterKey"/>
</Window.Resources>
<StackPanel>
<ListBox>
<ListBoxItem view:GridBehavior.IsTextMatch="True"
view:GridBehavior.CellsCounter="{StaticResource CounterKey}"
Content="a"/>
<ListBoxItem view:GridBehavior.IsTextMatch="False"
view:GridBehavior.CellsCounter="{StaticResource CounterKey}"
Content="b"/>
<ListBoxItem view:GridBehavior.IsTextMatch="False"
view:GridBehavior.CellsCounter="{StaticResource CounterKey}"
Content="c"/>
<ListBoxItem view:GridBehavior.IsTextMatch="True"
view:GridBehavior.CellsCounter="{StaticResource CounterKey}"
Content="d"/>
</ListBox>
<TextBlock Text="{Binding Path=Count,Source={StaticResource CounterKey}}"/>
</StackPanel>
</Window>
N.B。您需要更进一步,仔细增强删除逻辑。例如,现在如果从列表中删除IsTextMatch = true的项目,它不会影响计数器。我相信,你有足够的技巧可以自己做到这一点。