Привязки трех вложенных списокв

161
07 декабря 2021, 01:00

Подскажите пожалуйста как привязать 3 вложенных списка:

в ViewModel есть список проектов:

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Project> Projects{ get; set; } = new ObservableCollection<Project>();
    private Project selProject;
    public Project SelProject {
        get { return selProject; }
        set
        {
            selProject = value;
            OnPropertyChanged("SelProject");
        }
    }
    private Project selSec;
    public Project SelSec
    {
        get { return selSec; }
        set
        {
            selSec = value;
            OnPropertyChanged("SelSec");
        }
    }
    public ViewModel()
    {
        var pr1 = new Project("pr1");
        ObservableCollection<Section> sec = new ObservableCollection<Section> { new Section("sec1"), new Section("sec2") };
        ObservableCollection<Model> models = new ObservableCollection<Model> { new Model("model1"), new Model("model2") };
        sec.First().Models.Add(models.First());
        sec.First().Models.Add(models.Last());
        sec.Last().Models.Add(models.First());
        sec.Last().Models.Add(models.Last());
        pr1.Sections.Add(sec.First());
        pr1.Sections.Add(sec.Last());
        Projects.Add(pr1);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

класс Project:

 public class Project
{
    public string Projectname { get; set; }
    public ObservableCollection<Section> Sections { get; set; } = new ObservableCollection<Section>();
    public Project(string name)
    {
        Projectname = name;
    }
}

в котором есть список разделов:

public class Section
{
    public string SectionName { get; set; }
    public ObservableCollection<Model> Models { get; set; } = new ObservableCollection<Model>();
    public Section (string name )
    {
        SectionName = name;
    }
}

в списке разделов есть список моделей:

public class Model
{
    public string ModelName { get; set; }
    public Model (string name)
    {
        ModelName = name;
    }
}

делаю привязку так:

<ListBox Grid.Column="0" ItemsSource="{Binding Projects}"
             SelectedItem="{Binding SelProject}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="5">
                    <TextBlock FontSize="12" Text="{Binding Path=Projectname}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <StackPanel Grid.Column="1" Orientation="Horizontal" DataContext="{Binding SelProject}">
        <ListBox   ItemsSource="{Binding Sections}" SelectedItem="{Binding SelSec}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="5">
                        <TextBlock FontSize="12" Text="{Binding Path=SectionName}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ListBox  ItemsSource="{Binding SelSec.Models}" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="5">
                        <TextBlock FontSize="12" Text="{Binding Path=ModelName}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>

но последний ListBox не показывает список моделей, что я делаю не так?

Answer 1
<Grid.ColumnDefinitions>
        <ColumnDefinition Width="100"/>
        <ColumnDefinition Width="100"/>
        <ColumnDefinition Width="100"/>
    </Grid.ColumnDefinitions>
    <ListBox Grid.Column="0" 
             Name="List1" 
             ItemsSource="{Binding Projects}"
            SelectedItem="{Binding SelProject}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="5">
                    <TextBlock FontSize="12" Text="{Binding Path=Projectname}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ListBox Grid.Column="1" 
             Name="List2" 
             DataContext="{Binding ElementName=List1, Path=SelectedItem}" 
             ItemsSource="{Binding Sections}" 
             SelectedItem="{Binding SelSec}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="5">
                    <TextBlock FontSize="12" Text="{Binding Path=SectionName}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ListBox Grid.Column="2"  
             DataContext="{Binding ElementName=List2, Path=SelectedItem}" 
             ItemsSource="{Binding Models}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="5">
                    <TextBlock FontSize="12" Text="{Binding Path=ModelName}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

Плюс, можешь не писать в OnPropertyChanged("SelSec") наименование свойства, а можно просто OnPropertyChanged(), потому что в параметре метода написан атрибут CallerMemberName [CallerMemberName]string prop = "", он автоматически подхватывает наименование свойства

READ ALSO
Чем выполнить JS?

Чем выполнить JS?

Средствами POST запроса, от сервера приходит объект JSON

85
Декодирование URL

Декодирование URL

Нужно декодировать URL

108
Как получить информацию о свободном месте на диске сервера в локальной сети?

Как получить информацию о свободном месте на диске сервера в локальной сети?

Есть какой-то способ получить информацию о заполненности диска на сервере в локальной сети? Если это Windows-сервер, то можно воспользоваться...

272
Нет связи клиент - сервер

Нет связи клиент - сервер

Сервер - aspnet core web API, клиент - Angular 8 на сервере создаю метод

250