我无法将新数据添加到DataGrid



我一直在搜索这样的问题,并对我的代码进行了很多更改,但我无法解决它。

我创建了一个DataGrid:

<DataGrid Grid.Row="1" ItemsSource="{Binding VarDt}"  AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ID" Binding="{Binding Id}"/>
</DataGrid.Columns>
</DataGrid>

我使用的类的列表在Main模型中。

private List<ObjectVariable> _varDt;
public List<ObjectVariable> VarDt
{
get { return _varDt; }
set 
{ 
_varDt = value;
OnPropertyChanged("VarDt");
}
}

当我第一次添加数据时,它起作用了,我可以在我的DataGrid:中看到值

public MainViewModel()
{
VarDt = new List<ObjectVariable>()
{
new ObjectVariable { Id="9846849", Name="Val1" },
new ObjectVariable { Id="fregreg", Name="Val2" },
new ObjectVariable { Id="cd6s8s6", Name="Val3" }
}; [...]

但是,当我在执行命令时添加新项目时(当双击树项目时(,DataGrid会进行更新。(我添加新项目的代码,它不起作用(:

private ICommand _selectItemCommand;
public ICommand selectItemCommand
{
get
{
return _selectItemCommand ?? (_selectItemCommand = new RelayCommand(param => this.LoadContent(param)));
}
}
private void LoadContent(object selectedMenuItem)
{
// NEW ITEM THAT IS NOT ADDED WHY???
VarDt.Add(new ObjectVariable { Id = "cw61851cw", Name = "ValPost" });          
}

我不知道我是否没有正确地引发PropertyChanged事件,以及我如何才能做到这一点。

有人可以告诉我如何将数据正确添加到DataGrid中。

谢谢!

编辑1:仍然无法使用可观察的集合

声明:

private ObservableCollection<ObjectVariable> _varDt;
public ObservableCollection<ObjectVariable> VarDt
{
get { return _varDt; }
set 
{ 
_varDt = value;
OnPropertyChanged("VarDt");
}
}

Public MainViewModel((:

VarDt = new ObservableCollection<ObjectVariable>()
{
new ObjectVariable { Id="9846849", Name="ValuesAtStart1" },
new ObjectVariable { Id="fregreg", Name="ValuesAtStart2" },
new ObjectVariable { Id="cd6s8s6", Name="ValuesAtStart3" }
};

命令:

private void LoadContent(object selectedMenuItem)
{
// NEW ITEM THAT IS NOT ADDED WHY???
VarDt.Add(new ObjectVariable { Id = "cw61851cw", Name = "ValueInsideCommand" });
}

结果(未添加来自命令的数据(:

未添加命令内的值

编辑2:发现问题,但我没有解决方案

我遇到问题的DataGrid位于我用另一个类和ContentControl:管理的另一个视图中

实际上我有:

  • MainViewModel和MainView
  • VariablesViewModel和我放在ContentControl中的VariablesView。VariablesViewModel是空的,我只使用它来显示VariablesView

当我执行一个命令时,我会在ContentControl:中显示VariablesView

private void LoadContent(object selectedMenuItem)
{
TreeItemModel ItemSelected = (TreeItemModel)selectedMenuItem;
if (ItemSelected.Name == "Object variables")
{
// Current view is VariablesView
CurrentView = VariableVM;
// NEW ITEM THAT IS NOT ADDED WHY???
VarDt.Add(new ObjectVariable { Id = "cw61851cw", Name = "ValueInsideCommand" });
}

else CurrentView = "";
}

我意识到,我在ContentControl中显示的VariablesView中的DataGrid不会更新值,但如果我在主视图中放置相同的DataGrid,值就会更新。

也许问题在于;VarDt";在MainViewModel中,而不是在VariablesViewModel中。但我可以显示一些数据,(只有新值没有显示(

测试代码:

[...]
<ContentControl Grid.Column="1"
Margin="10"
Content="{Binding CurrentView}"/>
<DataGrid Grid.Row="3" Grid.Column="2" ItemsSource="{Binding VarDt}"  AutoGenerateColumns="True" />
[...]

测试结果代码:在MainView 中使用ContentControl os DataGrid的DataBinding结果

编辑3:完整上下文

变量视图:

<UserControl x:Class="AOE.MVVM.View.VariablesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:viewmodel="clr-namespace:AOE.MVVM.ViewModel"  
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:local="clr-namespace:AOE.MVVM.View"
mc:Ignorable="d" 
d:DesignHeight="450" d:DesignWidth="800">
<!--Asignación del archivo .cs a esta view-->
<UserControl.DataContext>
<viewmodel:MainViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions >
<RowDefinition Height="30*" MaxHeight="70"/>
<RowDefinition Height="100*"/>
<RowDefinition Height="10*" MaxHeight="30"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Image Source="/Media/Variables.png"
Height="50"
Width="50"
HorizontalAlignment="Left"/>
<TextBlock Text="Variables"
FontFamily="Verdana"
Foreground="#007BC0"/>
</StackPanel>
<DataGrid Grid.Row="1" ItemsSource="{Binding VarDt}"  AutoGenerateColumns="True" >
</DataGrid>
</Grid>

变量视图模型:空类。

AppXaml:

<Application x:Class="AOE.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AOE"
xmlns:viewModel="clr-namespace:AOE.MVVM.ViewModel"
xmlns:view="clr-namespace:AOE.MVVM.View"
StartupUri="MainWindow.xaml">
<Application.Resources>

<DataTemplate DataType="{x:Type viewModel:VariablesViewModel}">
<view:VariablesView/>
</DataTemplate>
</Application.Resources>

MainViewModel:

namespace AOE.MVVM.ViewModel
{
class MainViewModel : ObservableObject
{
public ObservableCollection<ObjectVariable> VarDt { get; set; }
//public TreeItemModel ItemSelected { get; set; }
private ICommand _selectItemCommand;
public ICommand selectItemCommand
{
get
{
return _selectItemCommand ?? (_selectItemCommand = new RelayCommand(param => this.LoadContent(param)));
}
}
private void LoadContent(object selectedMenuItem)
{
// Current view is VariablesView
CurrentView = VariableVM;
// NEW ITEM THAT IS NOT ADDED WHY???
VarDt.Add(new ObjectVariable { Id = "cw61851cw", Name = "ValueInsideCommand" });
}
public VariablesViewModel VariableVM { get; set; }
private object _currentView;
public object CurrentView
{
get { return _currentView; }
set
{
_currentView = value;
OnPropertyChanged("CurrentView");
}
}
public MainViewModel()
{
MainTree.Add(MainObject);
VarDt = new ObservableCollection<ObjectVariable>()
{
new ObjectVariable { Id="9846849", Name="ValuesAtStart1" },
new ObjectVariable { Id="fregreg", Name="ValuesAtStart2" },
new ObjectVariable { Id="cd6s8s6", Name="ValuesAtStart3" }
};
VariableVM = new VariablesViewModel();
}
}
}

VariablesView在XAML中将MainViewModel明确定义为其DataContext。这就是DataGrid显示初始值的原因:MainViewModel构造函数中的值。由于这是一个新实例,更改一个实例的值不会更改第二个实例的数值。

解决此问题的两个简单解决方案
一种解决方案可以是将VariablesViewDataContext绑定到原始MainViewModel实例
您可以定义一个RelativeSource来查找父ContentControl,并使用其DataContext作为DataContext绑定的源:

变量视图.xaml

<UserControl DataContext="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=DataContext}">
...
</UserControl>

第二个也是推荐的解决方案是使用从DataTemplate继承的天然DataContext

其结果是VariablesViewModel不能为空。如果MainViewModelVariablesViewModelVarDt属性一样共享数据,则不要重复这些属性。相反,将依赖于此共享属性的控件显式绑定到ContentControl(MainViewModel(的DataContext。与VariablesView相关的其他非共享数据必须移动到VariablesViewModel

以下示例假设VariablesView不是可重用的控件。不是,如果可重用性很重要,那么所有内部绑定都必须引用继承的DataContext。这意味着必须避免Binding.RelativeSource在UserControl之外查找源。

变量视图.xaml

<!-- DataContext is inherited from the DataTemplate and is the VariablesViewModel -->
<UserControl>
<!-- Bind explicitly to the shared data located in MainViewModel -->
<DataGrid ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=DataContext}" />
</UserControl>

最新更新