我有两个数据网格,两个都使用相同的xaml(除了一个有额外的列)。一个在主窗口中,另一个在用户控件中。两者都绑定到相同项目的集合(当前是一个ObservableCollection,另一个是数组)。项目使用MVVM(或近似值)。
一个数组/主窗口可以正常工作-“位置”组合框会加载选定的值(不为null的值),更改该值只会影响要在其中更改的行。
ObservableCollection / usercontrol没有。窗口打开时,“位置”列中的值不会加载,直到您向下滚动然后再次向上备份。更改“位置”组合框会更改在每个可见行(或在关闭虚拟化的情况下,每行)中显示的值...包括在禁用的组合框中。对于“绑定级别”组合框不会发生相同的事情,该组合框的处理方式基本上相同。无论显示的数据是数组还是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);
}
}
}
答案 0 :(得分:0)
原来与以下问题相同:WPF MVVM DataGridComboboxColumn change one row updates all
选定的答案(将IsSynchronizedWithCurrentItem设置为null)起作用。