WPF 数据网格中的闪烁行不起作用

本文关键字:闪烁 不起作用 数据 数据网 网格 WPF | 更新日期: 2023-09-27 18:35:25

我被WPF中的动画困住了。当该行中所有复选框选项都处于选中状态时,我需要在数据网格中对一行(闪烁)进行动画处理(共 3 个)。

<DataGrid x:Name="employeesGrid" SelectedItem="{Binding SelectedRow, Mode=TwoWay}" SelectedIndex="{Binding SelectedEmployeeIndex, Mode=TwoWay}" Style="{StaticResource dataGridStyle}" ItemsSource="{Binding Employees}">
        <DataGrid.ItemContainerStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=NumberOfSkills}" Value="3">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard x:Name="blinkingRow">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" RepeatBehavior="Forever" AutoReverse="true" />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <BeginStoryboard x:Name="notBlinkingRow">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="1" Duration="0:0:0.5" RepeatBehavior="Forever" AutoReverse="true" />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.ItemContainerStyle>
        <DataGrid.Columns>
            ...
            <DataGridTemplateColumn Header="Skills" IsReadOnly="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ListBox ItemsSource="{Binding Skills, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                                        Command="{Binding Path=DataContext.SaveChangesCommand, RelativeSource={RelativeSource Mode=Self}}" />
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            ...
    </DataGrid>

在视图模型我有。

public int NumberOfSkills 
    {
        get 
        {
            int count = 0;
            foreach(Skill skill in ((EmployeeViewModel)SelectedRow).Skills)
            {
                if(skill.IsChecked)
                {
                    count++;
                }
            }
            return count;
        }
    }

为什么这不起作用?我尝试了很多在互联网上找到的解决方案,但没有什么是不起作用的。发布的示例与msdn网站上的代码非常相似,所以我真的不知道这里有什么问题。

WPF 数据网格中的闪烁行不起作用

您需要解决几个问题才能解决此问题。

get 
{
    int count = 0;
    foreach(Skill skill in ((EmployeeViewModel)SelectedRow).Skills)
    {
        if(skill.IsChecked)
        {
            count++;
        }
    }
    return count;
}

在属性的 get 中,您应该只返回值,而不应更改任何值。它违反了 - [命令查询分离原则][1]

而只是返回私有变量_count

private int _count
public int NumberOfSkills
{
 get
 {
  return _count;
 }
 set
 {
  _count = value;
  NotifyPropertyChanged("NumberOfSkills")
 }
}

现在问题来了,你应该在哪里设置技能数量的逻辑?所以你应该保留在用户/参与者改变它的地方。

假设您设置IsChecked属性是由类技能的用户从 UI 设置的。您可以订阅 IsChecked PropertyChanged() 并分离更新 NumberOfSkills 的逻辑。

skill.PropertyChanged += SkillsPropertyChanged
SkillsPropertyChanged(Object sender, PropertyChangedEventArgs e)
{
  if(e.PropertyName ="IsChecked")
  { 
    //Logic to update the NumberOfSkills
    if(skill.IsChecked)
    {
        NumberOfSkills++;
    }
    else
    {
        NumberOfSkills--;
    }
  }
}

使用现有方法执行此操作的快速和简短方法很简单。只需在设置IsCheckedProperty时调用NotifyPropertyChanged("NumberOfSkills")即可。虽然这可能不是直截了当的,但希望你明白这个想法。

private bool _isChecked;
public bool IsChecked
{
 get {return _isChecked;}
 set 
 {
   _isChecked = value;
   NotifyPropertyChanged("IsChecked");
   NotifyPropertyChanged("NumberOfSkills");
 }
}