c# - 当只有显式更改的行应该被更改时,datagrid 中的多行正在更改
问题描述
我有两个数据网格,都使用相同的 xaml(除了一个有额外的列)。一个在主窗口中,另一个在用户控件内。两者都绑定到相同项目的集合(一个当前是 ObservableCollection,另一个是数组)。项目使用 MVVM(或近似值)。
数组/主窗口一个正常工作 - 位置组合框加载到选定的值(它不为空)并且更改该值只会影响它被更改的行。
ObservableCollection/usercontrol 没有。窗口打开时不会加载位置列中的值,直到您向下滚动然后再次向上滚动。更改位置组合框会更改每个可见行(或如果关闭虚拟化,则为每行)中显示的值......包括禁用的组合框。Bonding Level 组合框不会发生同样的情况,它的处理方式基本相同。无论呈现的数据是数组还是 ObservableCollection,都会发生这种情况。
用于生成行的类的每个实例都应该是完全独立的,没有代码隐藏来混淆值,并且在另一个文件中使用集合中完全相同的类型的极其相似的 xaml 和 c# 工作。我搞不清楚了!
截图如下:
正确的行为(主窗口、数组)
https://i.imgur.com/SJIsTOT.png (立即加载,禁用的组合框中没有值)
https://i.imgur.com/cmjaPoR.png (单行更改)
损坏的行为(用户控件嵌入到 tabcontrol、ObservableCollection)
https://i.imgur.com/yC3iAas.png (未在打开的窗口上加载)
https://i.imgur.com/aQgPMCN.png (滚动后加载,包括无效值)
https://i.imgur.com/dqo39aB.png (一个组合框改变,所有行改变)
DataGrid 的 XAML 和行为不端的组合框列(无绑定错误):
<DataGrid Grid.Row ="1" Width="Auto" Height="Auto" AlternatingRowBackground="#FBE9D9" AlternationCount="2"
AutoGenerateColumns="False" GridLinesVisibility="None"
ItemsSource="{Binding Familiars}" IsSynchronizedWithCurrentItem="True">
<DataGrid.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding OpenDataFamiliarWindow}" CommandParameter="{Binding Familiars/}"/>
</DataGrid.InputBindings>
<DataGrid.Resources>
<local_c:OwnedToBoolConverter x:Key="OwnedToBoolConverter"/>
<local_c:EnemyTypeToColourConverter x:Key="EnemyTypeToColour"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
</DataGrid.Resources>
<DataGridTemplateColumn Header="Location" Width="Auto" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding AvailableLocationTypes}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="90"
SelectedItem="{Binding Info.Location, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsSynchronizedWithCurrentItem="True" IsEnabled="{Binding Info.Owned, Converter={StaticResource OwnedToBoolConverter}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource DescConverter}, Mode=OneTime}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
UserControl 旨在绑定到的类(以及与本质上相同的数据网格的工作使用不同的唯一位):
public class ColiseumVenue : INotifyPropertyChanged
{
public BitmapImage HeaderImage { get; private set; }
public string Name { get; private set; }
public ObservableCollection<FamiliarViewModel> Familiars { get; private set; } = new ObservableCollection<FamiliarViewModel>();
private IModel m_Model;
public ColiseumVenue(IModel model, string name, IEnumerable<FamiliarViewModel> familiars)
{
Name = name;
m_Model = model;
HeaderImage = ImageLoader.LoadImage(Path.Combine(ApplicationPaths.GetViewIconDirectory(), name + ".png"));
foreach(var familiar in familiars)
{
Familiars.Add(familiar);
}
}
public ColiseumView Window { get; set; }
private BaseCommand m_openDataFamiliarWindow;
public ICommand OpenDataFamiliarWindow
{
<snip>
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
FamiliarViewModel 类的公共变量是:
public class FamiliarViewModel : INotifyPropertyChanged
{
public FamiliarInfo Info { get; set; }
public LocationTypes[] AvailableLocationTypes { get; private set; }
public OwnershipStatus[] AvailableOwnershipStatuses { get; private set; }
public BondingLevels[] AvailableBondingLevels { get; private set; }
public BookmarkState[] AvailableBookmarkStates { get; private set; }
}
FamiliarInfo 类中绑定的部分是:
public ICRUD<OwnedFamiliar> OwnedFamiliar
{
get { return m_OwnedFamiliar; }
set
{
if(m_OwnedFamiliar != value)
{
m_OwnedFamiliar = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Owned"));
}
}
}
public OwnershipStatus Owned => OwnedFamiliar != null ? OwnershipStatus.Owned : OwnershipStatus.NotOwned;
public BondingLevels? BondLevel
{
get
{
return OwnedFamiliar?.Fetch()?.BondingLevel;
}
set
{
if (value.HasValue)
{
OwnedFamiliar?.Update(f => f.BondingLevel = value.Value);
}
}
}
public LocationTypes? Location
{
get
{
return OwnedFamiliar?.Fetch()?.Location;
}
set
{
if (value.HasValue)
{
OwnedFamiliar?.Update(f => f.Location = value.Value);
}
}
}
解决方案
结果与以下问题相同:WPF MVVM DataGridComboboxColumn change one row updates all
所选答案(将 IsSynchronizedWithCurrentItem 设置为 null)有效。
推荐阅读
- json - 如何合并多个 PostgreSQL JSON 数组,这些数组是另一个 JSON 数组更新其所有元素的结果?
- python - 如何在 Python 中将多键 dict 写入 excel?
- javascript - 通过应用脚本在 Google 驱动器中以不受支持的格式上传的图像
- javascript - 如何递归地将一个数据集转换为另一个数据集?
- python - requests.exceptions.MissingSchema:无效的 URL Python API 获取请求
- javascript - 我有一个打印数字的 for 循环。但我不希望它打印几个数字
- amazon-s3 - Material ui dropzone S3 上传器
- javascript - 只有当我点击“新建”选项时,我才能打开我的模式?
- ansible - Ansible - 使用来自 vars 的一个或多个参数运行 shell 命令
- c - 从标准输入传递函数名并在 C 中执行