DataContext更新后,控件事件将多次运行

时间:2019-04-15 06:14:48

标签: c# wpf mvvm

我有一个带有“模板”列的DataGrid作为复选框,其中包含用于某些计算和数据比较的选中/取消选中事件,还有一个文本框,允许我使用“按名称搜索”字段并隐藏无用的结果:

DataGrid.xaml

<TextBox Name="TbSearch"
             Grid.Row="0"
             Background="#F5F5F5"
             BorderBrush="#F5F5F5"
             Padding="27,6,0,0"
             Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<DataGrid Name="DgViews"
      Grid.Row="1" 
      AutoGenerateColumns="False"
      IsReadOnly="True"
      ItemsSource="{Binding Views}">

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsVisible}" Value="False">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>

<DataGrid.Columns>
    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <CheckBox Tag="{Binding UniqueId}"
                          IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}"
                          Checked="ViewCheck"
                          Unchecked="ViewUncheck"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Width="*" 
                        Header="View name"
                        Binding="{Binding ViewName}"/>
    <DataGridTextColumn Width="*" 
                        Header="View type"
                        Binding="{Binding ViewType}"/>
</DataGrid.Columns>

DataGridTest.xaml.cs

public DataGridTest()
{
    InitializeComponent();
    DataContext = new ModelDataContext();
}

private void ViewCheck(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Checked");
}

private void ViewUncheck(object sender, RoutedEventArgs e)
{
    MessageBox.Show("UnChecked");
}

ModelDataContext.cs

class ModelDataContext : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string searchText = string.Empty;

    public ModelDataContext()
    {

    }

    public string SearchText
    {
        get => searchText;
        set
        {
            searchText = value;

            Views = Views.Select(n =>
            {
                if (n.ViewName.ToLower().Contains(searchText.ToLower()))
                {
                    n.IsVisible = true;
                }
                else
                {
                    n.IsVisible = false;
                }
                return n;
            }).ToList();

            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Views"));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SearchText"));
        }
    }

    public List<ViewData> Views { get; set; }
}

当我键入搜索文本时,DataGrid项目源每次都会更新,并且通过每次更新,复选框事件(选中/取消选中)将增加一。 例如,我键入3个字母,数据网格更新3次,所以当我选中复选框时,它可以工作3次,但是我只需要一次。 我该怎么解决?

1 个答案:

答案 0 :(得分:1)

在ViewData类更新IsVisible属性中

 private bool _IsVisible;
   public bool IsVisible
     {
       get { return _IsVisible; }
       set { _IsVisible = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsVisible")); }
     } 

从SearchText中删除重新分配视图,

 public string SearchText
    {
        get => searchText;
        set
        {
            searchText = value;

             Views.Select(n =>
            {
                if (n.ViewName.ToLower().Contains(searchText.ToLower()))
                {
                    n.IsVisible = true;
                }
                else
                {
                    n.IsVisible = false;
                }
                return n;
            }).ToList();

            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Views"));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SearchText"));
        }
    }