WPF绑定到三级ObservableCollection <t>属性

时间:2018-11-15 12:43:04

标签: c# wpf mvvm binding observablecollection

我有3个级别的子类,彼此具有ObservableCollection<T>属性。在MainViewModel中,我创建了ObservableCollection<Group>属性,其中Group类的元素将位于TreeView中的第一级。在每个Group类中,我创建了子ObservableCollection<Parameter>属性。最后,在Parameter类中,我为存储值创建了ObservableCollection<ParameterValue>。注意:每个基于INotifyPropertyChanged接口的类。我们去编写代码。

Models.cs

//BaseModel implement INotifyPropertyChanged
public class ParameterValue: BaseModel
{
    private DateTime dateTimeValue;
    public DateTime DateTimeValue
    {
        get { return dateTimeValue; }
        set
        {
            dateTimeValue = value;
            NotifyPropertyChanged("DateTimeValue");
        }
    }

    private double value;
    public double Value
    {
        get { return value; }
        set
        {
            this.value = value;
            NotifyPropertyChanged("Value");
        }
    }
}

//BaseModel implement INotifyPropertyChanged
public class Parameter: BaseModel
{
    public Parameter()
    {
        values = new ObservableCollection<ParameterValue>();
    }

    private ObservableCollection<ParameterValue> values;
    public ObservableCollection<ParameterValue> Values
    {
        get { return values; }
        set
        {
            values = value;
            NotifyPropertyChanged("Values");
        }
    }

    private int parameterId;
    public int ParameterId
    {
        get { return parameterId; }
        set
        {
            parameterId = value;
            NotifyPropertyChanged("ParameterId");
        }
    }

    private string parameterName;
    public string ParameterName
    {
        get { return parameterName; }
        set
        {
            parameterName = value;
            NotifyPropertyChanged("ParameterName");
        }
    }
}

//BaseModel implement INotifyPropertyChanged
public class Group: BaseModel
{
    public Group()
    {
        parameters = new ObservableCollection<Parameter>();
    }

    private ObservableCollection<Parameter> parameters;
    public ObservableCollection<Parameter> Parameters
    {
        get { return parameters; }
        set
        {
            parameters = value;
            NotifyPropertyChanged("Parameters");
        }
    }

    private int groupId;
    public int GroupId
    {
        get { return groupId; }
        set
        {
            groupId = value;
            NotifyPropertyChanged("Id");
        }
    }

    private string groupName;
    public string GroupName
    {
        get { return groupName; }
        set
        {
            groupName = value;
            NotifyPropertyChanged("GroupName");
        }
    }
}

//Implementing INotifyPropertyChanged
public class BaseModel: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ViewModels.cs

//BaseModel implement INotifyPropertyChanged
public class MainViewModel: BaseModel
{
    public MainViewModel()
    {
        groups = new ObservableCollection<Group>();

        //fill sample data instead of recieving from DB
        for (int i = 1; i < 11; i++)
        {
            Group group = new Group { GroupId = i, GroupName = "Group " + i.ToString()};
            groups.Add(group);
            for (int j = 1; j < 11; j++)
            {
                Parameter param = new Parameter { ParameterId = j, ParameterName = "Parameter "+j.ToString()};
                for (int k = 1; k < 51; k++)
                {
                    ParameterValue val = new ParameterValue { DateTimeValue = DateTime.Now.AddSeconds(i*j-k), Value = (1000-k*5)/((i+j)+1)};
                    param.Values.Add(val);
                }
                group.Parameters.Add(param);
            }
        }

        int l = 0;
    }

    private ObservableCollection<Group> groups;
    public ObservableCollection<Group> Groups
    {
        get { return groups; }
        set
        {
            groups = value;
            NotifyPropertyChanged("Groups");
        }
    }
}

和MainWindow.xaml一起充当查看角色:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="25*" />
        <ColumnDefinition Width="75*" />
    </Grid.ColumnDefinitions>
    <TreeView x:Name="trv" Grid.Column="0" ItemsSource="{Binding Groups}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Parameters}">
                <TextBlock Text="{Binding GroupName}" />
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding ParameterName}"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    <ListView Grid.Column="1" Background="Bisque" ItemsSource="{Binding Path=Groups.Parameters}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Date Time" DisplayMemberBinding="{Binding DateTimeValue}"/>
                <GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

MainViewModel中,我简化了从DB接收的数据,将其替换为嵌套有测试数据的for循环。

  1. 我尝试以MVVM方式在TreeView的{​​{1}} Parameter数据中选择显示。
  2. ListView中创建DataGroup类的SelectedItem属性所必需,以便更准确地从DB接收数据吗?当然以MVVM方式。

1 个答案:

答案 0 :(得分:1)

在ListView ItemSource中,您必须像这样绑定到值...

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="25*" />
        <ColumnDefinition Width="75*" />
    </Grid.ColumnDefinitions>
    <TreeView x:Name="trv" Grid.Column="0" ItemsSource="{Binding Groups}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Parameters}">
                <TextBlock Text="{Binding GroupName}" />
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding ParameterName}"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    <ListView Grid.Column="1" 
              Background="Bisque" 
              ItemsSource="{Binding SelectedItem.Values, ElementName=trv}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Date Time" DisplayMemberBinding="{Binding DateTimeValue}"/>
                <GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

观察者如何绑定到TreeView的SelectedItem。该选定的项目应该是具有Values属性的参数。

如果选择“组”,则由于“组”没有“值”集合,将不显示任何内容。只有参数具有该功能。

相关问题