[英]C# WPF MVVM - How to populate ObservableCollection then later load data in listview?
so, i have a mainviewmodel and a secondviewmodel, my ObservableCollection is in the secondviewmodel, but i want to populate it from mainviewmodel and then later in the program i would want to load a popup with a listview that has the data loaded from earlier. 因此,我有一个mainviewmodel和secondviewmodel,我的ObservableCollection在secondviewmodel中,但是我想从mainviewmodel填充它,然后在程序中稍后要加载一个带有listview的弹出窗口,该listview具有从先前加载的数据。 I don't want to add data in the list from the View. 我不想在“视图”列表中添加数据。 I was thinking about this, until now only if i add data from the secondviewmodel shows on the popup when i open it. 我一直在考虑这个问题,直到现在为止,只有当我打开第二个视图模型中的数据并在弹出窗口中显示时,才开始这样做。
<Grid Background="Gainsboro" >
<Grid.DataContext>
<vm:AdminViewModel/>
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Command="{Binding GenerateCommand}" Grid.Column="2" Height="30" Width="55" x:Name="btnGenerate" Margin="5,5,5,0" FontSize="8.5" VerticalAlignment="Top" HorizontalAlignment="Center" Content="Generate"/>
<StackPanel Grid.Row="1" Grid.Column="0">
<Border BorderThickness="1" BorderBrush="Black">
<Grid DataContext="{Binding}" Width="300" Height="300" Background="Gainsboro" Margin="0">
<Grid.RenderTransform>
<RotateTransform x:Name="theTransform" />
</Grid.RenderTransform>
<Button Width="50" Height="50" HorizontalAlignment="Left" Command="{Binding AbortCommand, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" VerticalAlignment="Bottom" Content="Abort"/>
<TreeView>
<TreeView.DataContext>
<vm:ReportViewModel/>
</TreeView.DataContext>
<TreeViewItem Header="Error" IsExpanded="True">
<ListView ItemsSource="{Binding Error}">
</ListView>
</TreeViewItem>
<TreeViewItem Header="Warning" IsExpanded="True">
<ListView ItemsSource="{Binding Warning}">
</ListView>
</TreeViewItem>
<TreeViewItem Header="Information" IsExpanded="True">
<ListView ItemsSource="{Binding Information}">
</ListView>
</TreeViewItem>
</TreeView>
</Grid>
</Border>
</StackPanel>
</Grid>
class AdminViewModel : ViewModelBase
{
private RelayCommand generateCommand;
public RelayCommand GenerateCommand { get { return generateCommand; } }
private ReportViewModel rvm;
public AdminViewModel()
{
generateCommand = new RelayCommand(o => { Generate(); }); //bind UI button to this command
rvm = new ReportViewModel();
}
private void Generate()
{
if (CadFilePath == string.Empty)
{
rvm.LogError("Warning", "This is a warning"); //this should add the string "This is warning" in the ObservableCollection called Warning in the secondviewmodel
}
}
}
class ReportViewModel : ViewModelBase
{
private ObservableCollection<string> error;
public ObservableCollection<string> Error
{
get { return error; }
set
{
error = value;
OnPropertyChanged("Error");
}
}
private ObservableCollection<string> warning;
public ObservableCollection<string> Warning
{
get { return warning; }
set
{
warning = value;
OnPropertyChanged("Warning");
}
}
private ObservableCollection<string> information;
public ObservableCollection<string> Information
{
get { return information; }
set
{
information = value;
OnPropertyChanged("Information");
}
}
public ReportViewModel()
{
error = new ObservableCollection<string>();
warning = new ObservableCollection<string>();
information = new ObservableCollection<string>();
Warning.Add("Warning"); //this is showing in UI
Warning.Add("Warning2"); //this is showing in UI
Error.Add("404"); // this is showing in UI
Information.Add("INFO"); //this is showing in UI
}
public void LogError(string severity, string err)
{
if (severity == "Warning")
{
Warning.Add(err);
}
if (severity == "Error")
{
Error.Add(err);
}
if (severity == "Information")
{
Information.Add(err);
}
}
You are creating another instance of view model in this line: (remove this) 您将在此行中创建另一个视图模型实例:(删除此)
<TreeView.DataContext>
<vm:ReportViewModel/>
</TreeView.DataContext>
What you should have done is to read an existing instance of the view model instead: (add this) 您应该做的是改为读取视图模型的现有实例:(添加此内容)
<TreeView DataContext="{Binding Rvm}">
And obviously you'd need to have a public property for ReportViewModel
in AdminViewModel
for that to work: (add this) 显然,您需要在AdminViewModel
具有ReportViewModel
的公共属性才能起作用:(添加此内容)
public ReportViewModel Rvm { get { return rvm; } }
you need Rvm
defined like that because the binding source must be a public property
您需要Rvm
定义Rvm
,因为绑定源必须是public property
you won't need to notify changes for Rvm
(and also for the 3 collections) since you only set their value in the constructor and you never change them later on. 您无需通知Rvm
(以及3个集合)的更改,因为您仅在构造函数中设置了它们的值,以后再也不会更改它们。
A good practice for ObservableCollection
is to create a snippet out of the following code: ObservableCollection
一个好习惯是使用以下代码创建一个代码段:
private ObservableCollection<string> warning = new ObservableCollection<string>();
public ObservableCollection<string> Warning { get { return warning; } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.