当仅应明确更改的行

时间:2018-12-15 00:06:41

标签: c# wpf mvvm datagrid

我有两个数据网格,两个都使用相同的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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

原来与以下问题相同:WPF MVVM DataGridComboboxColumn change one row updates all

选定的答案(将IsSynchronizedWithCurrentItem设置为null)起作用。