【发布时间】:2013-06-07 22:11:17
【问题描述】:
所有,我创建了一个DataGrid,上面有一个搜索框。当用户键入并在DataGrid 中找到文本时,匹配单元格的背面颜色为橙色。我已经做到了这一点,但现在(回顾性地)想要将搜索 TextBox 的 BorderBrush 更改为“红色”,如果 没有 找到文本(否则默认)。控件的 XAML 是
<UserControl x:Class="ResourceStudio.Views.ResourceControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewModels="clr-namespace:ResourceStudio.ViewModels"
xmlns:dataAccess="clr-namespace:ResourceStudio.DataAccess"
xmlns:controls="clr-namespace:ResourceStudio.Controls"
mc:Ignorable="d">
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBox DockPanel.Dock="Top" Name="searchBox" BorderBrush="#FF007ACC" BorderThickness="2">
<TextBox.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="dataAccess:DataGridTextSearch.IsTextMatch" Value="False">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Resources>
</TextBox>
<Grid DockPanel.Dock="Top">
<Border>
<controls:ResourceDataGrid ItemsSource="{Binding Path=Resources}"
dataAccess:DataGridTextSearch.SearchValue="{Binding ElementName=searchBox,
Path=Text, UpdateSourceTrigger=PropertyChanged}">
<controls:ResourceDataGrid.Columns>
<DataGridTextColumn Header="KeyIndex" Binding="{Binding KeyIndex}" IsReadOnly="True"/>
<DataGridTextColumn Header="FileName" Binding="{Binding FileName}" IsReadOnly="True"/>
<DataGridTextColumn Header="ResourceName" Binding="{Binding ResourceName}" IsReadOnly="False"/>
<controls:CollectionTextColumn Collection="ResourceStringList" Visibility="Collapsed"/>
</controls:ResourceDataGrid.Columns>
<controls:ResourceDataGrid.Resources>
<dataAccess:SearchValueConverter x:Key="searchValueConverter"/>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="dataAccess:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource searchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
<Binding RelativeSource="{RelativeSource Self}" Path="(dataAccess:DataGridTextSearch.SearchValue)" />
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="dataAccess:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="Orange" />
</Trigger>
</Style.Triggers>
</Style>
</controls:ResourceDataGrid.Resources>
</controls:ResourceDataGrid>
</Border>
</Grid>
</DockPanel>
</UserControl>
我的基本Trigger TextBox 什么都不做。 如何使用与DataGrid 相同的机制更改TextBox BorderBrush 的颜色?
感谢您的宝贵时间。
编辑。管理DependencyProperty 和IConverter 的类是
public static class DataGridTextSearch
{
public static readonly DependencyProperty SearchValueProperty =
DependencyProperty.RegisterAttached("SearchValue", typeof(string), typeof(DataGridTextSearch),
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 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);
}
}
public class SearchValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
string cellText = values[0] == null ? String.Empty : values[0].ToString();
string searchText = values[1] as String;
if (!string.IsNullOrEmpty(searchText) &&
!string.IsNullOrEmpty(cellText))
{
return cellText.ToLower().StartsWith(searchText.ToLower());
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
【问题讨论】:
-
如果您在
DataGrid中使用虚拟化,这将有点棘手,问题是IsTextMatch属性已注册到DataGrid中的个人Cells不是全局实例,如果找不到文本,要更改TextBox,您需要迭代DataGrid中的所有Cells并检查是否有附加属性集,如果你设置了虚拟化必须渲染所有项目以检查其是否匹配。 -
也许你可以在单元格上使用 EventSetter 在你的视图中设置一个公共布尔值来设置
TextBox边框是否应该是红色的,因为这是所有与事件相关的视图' t 打破 MVVM 模式。