WPF诡异问题
我Prism版本没更新,WPF未更新,但是只隔了几天,程序出问题了????
1、程序打开颜色不变化,手动修改值两次后颜色变化(失败)
<DataGrid
Name="down"
Grid.Row="1"
Margin="5"
VerticalAlignment="Top"
AutoGenerateColumns="False"
CanUserSortColumns="False"
DisplayMemberPath="Name"
ItemsSource="{Binding Students}"
RowHeaderWidth="0"
SelectedValuePath="Name">
<DataGrid.Columns>
<DataGridTextColumn
Width="150"
Binding="{Binding Id}"
Header="Id" />
<DataGridTextColumn
Width="150"
Binding="{Binding Name}"
Header="姓名">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding IsChanged, Converter={StaticResource BoolToColorConverter}}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
public class Stu : BindableBase
{
public int Id { get; set; }
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged(nameof(Name));
IsChanged = true;
}
}
}
private bool _isChanged = false;
public bool IsChanged
{
get => _isChanged;
set => SetProperty(ref _isChanged, value);
}
} public class ColorChangedViewModel : BindableBase
{
private ObservableCollection<Stu> _students;
public ObservableCollection<Stu> Students
{
get => _students ?? (_students = new ObservableCollection<Stu>());
set => SetProperty(ref _students, value);
}
public ColorChangedViewModel()
{
Students = new ObservableCollection<Stu>()
{
new Stu() { Id = 1,Name="lisi",},
};
}
2、几天前的成功方案,程序打开颜色不变化,手动修改值一次后颜色变化 (增加了UpdateSourceTrigger=PropertyChanged,成功)
<DataGrid
Name="down"
Grid.Row="1"
Margin="5"
VerticalAlignment="Top"
AutoGenerateColumns="False"
CanUserSortColumns="False"
DisplayMemberPath="Name"
ItemsSource="{Binding Students}"
RowHeaderWidth="0"
SelectedValuePath="Name">
<DataGrid.Columns>
<DataGridTextColumn
Width="150"
Binding="{Binding Id}"
Header="Id" />
<DataGridTextColumn
Width="150"
Binding="{Binding Name,UpdateSourceTrigger=PropertyChanged}"
Header="姓名">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding IsChanged, Converter={StaticResource BoolToColorConverter},UpdateSourceTrigger=PropertyChanged}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
public class Stu : BindableBase
{
public int Id { get; set; }
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged(nameof(Name));
IsChanged = true;
}
}
}
private bool _isChanged = false;
public bool IsChanged
{
get => _isChanged;
set => SetProperty(ref _isChanged, value);
}
} public class ColorChangedViewModel : BindableBase
{
private ObservableCollection<Stu> _students;
public ObservableCollection<Stu> Students
{
get => _students ?? (_students = new ObservableCollection<Stu>());
set => SetProperty(ref _students, value);
}
public ColorChangedViewModel()
{
Students = new ObservableCollection<Stu>()
{
new Stu() { Id = 1,Name="lisi",},
};
}
3、今天我重新打开代码,程序启动Name颜色就变红,我程序没改,所有类库未升级,我决定删除UpdateSourceTrigger=PropertyChanged,还是一样,程序打开Name颜色就变红和之前的完全不一样
4、经过我长时间的研究,最后的解决方案是
Students = new ObservableCollection<Stu>()
{
new Stu() { Id = 1,Name="lisi",IsChanged=false},
};
此时虽然 public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged(nameof(Name));
IsChanged = true;
}
}
}中将IsChanged改为true了,但是ColorChangedViewModel对Students进行初始化操作的时候重新设置false,所以成功(程序打开Name是黑色,修改Name颜色变为红色,)我想不明白几天前的代码为什么失效
DeepSeek说ObservableCollection会触发重置通知,但绑定系统可能不会立即刷新所有子项状态。
你的有效方案原理:
通过显式设置IsChanged=false,强制触发了属性通知,绕过了WPF的绑定优化机制
🌟 结论
不是玄学问题:根本原因是WPF绑定系统对集合重置和子项通知的优化策略存在不确定性。
你的解决方案有效:显式设置IsChanged=false实际上是通过强制属性通知,绕过了WPF的绑定缓存机制。
工业级建议:
在MVVM中初始化集合数据时,避免在对象初始化器中触发业务逻辑
对关键属性显式指定默认值而非依赖字段初始值
必要时手动触发PropertyChanged确保一致性
这种问题看似诡异,实则反映了WPF框架在性能和正确性之间的权衡。你的实践恰好找到了一个可靠的解决方案!
有了解的可以讨论下

浙公网安备 33010602011771号