简体   繁体   English

C#WPF MVVM-如何填充ObservableCollection,然后在列表视图中加载数据?

[英]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. 我一直在考虑这个问题,直到现在为止,只有当我打开第二个视图模型中的数据并在弹出窗口中显示时,才开始这样做。

XAMl XAML

<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>

This is the main view model 这是主视图模型

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

        }
    }
}

Second Viewmodel 第二视图模型

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; } }

edit 编辑

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM