Привязка WPF к трехуровневому свойству ObservableCollection <T> - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть 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 я упрощаю получение данных из БД, заменяя их вложенными циклами с тестовыми данными.

  1. Я пытаюсь сделать отображение выбранных в TreeView Parameter данных в ListView в формате MVVM.
  2. В DataGroup необходимо создать SelectedItem свойство Parameter класс для более точного получения данных из БД?Конечно в MVVM пути.

1 Ответ

0 голосов
/ 15 ноября 2018

В вашем 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>

Наблюдатель за тем, как я привязался к SelectedItem вашего TreeView. Предполагается, что выбранный элемент будет параметром со свойством Values.

Если вы выберете Группу, то ничего не будет отображаться, поскольку у Группы нет коллекции значений. Только параметр имеет это.

...