我正在根据论坛中的示例代码来开发DataGrid文本搜索功能。就我而言,没有固定的列,具体取决于SQL查询中的数据。
一切正常,直到我使用AutoGeneratingColumn在后面的代码中更改列的单元格对齐。 (这里创建了一个简单的示例来重现该问题)
Text Search Not Working for Column after Cell Alignment Change
[<Window.Resources>
<Style x:Key="CellAlignCenter" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TextBox x:Name="txtSearch"
Height="22" Width="80" VerticalAlignment="Top" Margin="10"/>
<DataGrid x:Name="dgTest"
Height="200" Width="300"
local:DataGridTextSearch.SearchValue="{Binding ElementName=txtSearch, Path=Text, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="True"
AutoGeneratingColumn="dgTest_AutoGeneratingColumn">
<DataGrid.Resources>
<local:SearchValueConverter x:Key="SearchValueConverter" />
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="local:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="Orange" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>][2]
后面的代码:
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, System.Globalization.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.Trim().ToLower().Contains(searchText.Trim().ToLower());
else
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
public class User
{
public string Name1 { get; set; }
public string Name2 { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<User> users = new List<User>();
users.Add(new User() { Name1 = "John Doe", Name2 = "John Doe" });
users.Add(new User() { Name1 = "Jane Doe", Name2 = "Jane Doe" });
dgTest.ItemsSource = users;
}
private void dgTest_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
string headerName = e.Column.Header.ToString();
Style styleAlignCenter = FindResource("CellAlignCenter") as Style;
if (headerName == "Name1")
e.Column.Width = 100;
else if (headerName == "Name2")
{
e.Column.Width = 100;
e.Column.CellStyle = styleAlignCenter;
}
}
}
当我从“隐藏代码”中更改单元格对齐方式时,就会发生这种情况。
DataGridCell的模板定义中缺少某些内容吗?
感谢帮助和建议。
答案 0 :(得分:1)
您的代码看起来不错,但是,当您从WPF后面的代码中更改DataGridCell
的样式时,也会从旧样式中删除样式元素(设置程序/触发器),因此只需从旧样式中派生新样式,您会没事的。
只需更改XAML文件即可
<Window.Resources>
<ResourceDictionary>
<local:SearchValueConverter x:Key="SearchValueConverter" />
<Style x:Key="DefaultGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="local:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="Orange" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="CellAlignCenter" TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource DefaultGridCellStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<TextBox x:Name="txtSearch"
Height="22" Width="80" VerticalAlignment="Top" Margin="10"/>
<DataGrid x:Name="dgTest"
Height="200" Width="300"
local:DataGridTextSearch.SearchValue="{Binding ElementName=txtSearch, Path=Text, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="True"
AutoGeneratingColumn="dgTest_AutoGeneratingColumn">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource DefaultGridCellStyle}">
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>