单元格对齐方式更改后WPF DataGrid文本搜索不工作

单元格对齐方式更改后WPF DataGrid文本搜索不工作,wpf,datagrid,Wpf,Datagrid,我正在基于论坛的示例代码开发DataGrid文本搜索功能。在我的例子中,没有固定的列,这取决于SQL查询中的数据 在我使用AutoGeneratingColumn在代码隐藏中更改列的单元格对齐方式之前,所有这些都可以正常工作。在这里创建了一个简单的示例来重现问题 代码隐藏: public static class DataGridTextSearch { public static readonly DependencyProperty SearchValuePro

我正在基于论坛的示例代码开发DataGrid文本搜索功能。在我的例子中,没有固定的列,这取决于SQL查询中的数据

在我使用AutoGeneratingColumn在代码隐藏中更改列的单元格对齐方式之前,所有这些都可以正常工作。在这里创建了一个简单的示例来重现问题

代码隐藏:

   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的模板定义中缺少某些内容?
感谢您的帮助和建议。

您的代码看起来不错,但是,当您从代码中更改DataGridCell的样式时,WPF也将从旧样式中删除样式元素设置器/触发器,所以只需从旧样式中派生新样式,您就可以了

唯一需要更改的是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>
在dgTest_AutoGeneratingColumn中,它使DataGrid中的默认样式无效。也许您应该尝试将CellAlignCenter样式中样式的BaseOn属性设置为基于在DataGrid中设置的默认样式
<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>