Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF MVVM层次结构所选项目_C#_Wpf_Mvvm_Collectionviewsource - Fatal编程技术网

C# WPF MVVM层次结构所选项目

C# WPF MVVM层次结构所选项目,c#,wpf,mvvm,collectionviewsource,C#,Wpf,Mvvm,Collectionviewsource,我目前正在使用列表框(请不要建议使用TreeView,列表框)实现显示层次结构的应用程序 看起来是这样的 课程: public class Mountains : ObservableCollection<Mountain> { public ObservableCollection<Lift> Lifts { get; } public string Name { get; } } public class Lift { public Ob

我目前正在使用
列表框
(请不要建议使用
TreeView
列表框
)实现显示层次结构的应用程序

看起来是这样的

课程:

public class Mountains : ObservableCollection<Mountain>
{
    public ObservableCollection<Lift> Lifts { get; }

    public string Name { get; }
}

public class Lift
{
    public ObservableCollection<string> Runs { get; }
}

也许我遗漏了一些基本原则,但我如何才能做到这一点?

您的ViewModel不应该也是一个集合,它应该包含绑定到视图的集合和属性。SelectedRun应该是此ViewModel(MountainViewModel)的属性,而不是Mountains。MountainViewModel应该公开Mountains集合和SelectedRun,并且应该绑定到列表框的ItemsSource和SelectedItem。

下面是我将如何做的。您希望确保在设置属性时触发INotifyPropertyChanged事件。要获得所选跑步,您必须获得MainViewModel.SelectedMountain.SelectedLift.SelectedRun

public class MainViewModel: ViewModelBae
{
    ObservableCollection<MountainViewModel> mountains
    public ObservableCollection<MountainViewModel> Mountains
    {
        get { return mountains; }
        set
        {
            if (mountains != value)
            {
                mountains = value;
                RaisePropertyChanged("Mountains");
            }
        }
    }
    MountainViewModel selectedMountain
    public MountainViewModel SelectedMountain
    {
        get { return selectedMountain; }
        set
        {
            if (selectedMountain != value)
            {
                selectedMountain = value;
                RaisePropertyChanged("SelectedMountain");
            }
        }
    }
}

public class MountainViewModel: ViewModelBae
{
    ObservableCollection<LiftViewModel> lifts
    public ObservableCollection<LiftViewModel> Lifts
    {
        get { return lifts; }
        set
        {
            if (lifts != value)
            {
                lifts = value;
                RaisePropertyChanged("Lifts");
            }
        }
    }
    LiftViewModel selectedLift
    public LiftViewModel SelectedLift
    {
        get { return selectedLift; }
        set
        {
            if (selectedLift != value)
            {
                selectedLift = value;
                RaisePropertyChanged("SelectedLift");
            }
        }
    }
}

public class LiftViewModel: ViewModelBae
{
    ObservableCollection<string> runs
    public ObservableCollection<string> Runs
    {
        get { return runs; }
        set
        {
            if (runs != value)
            {
                runs = value;
                RaisePropertyChanged("Runs");
            }
        }
    }
    string selectedRun
    public string SelectedRun
    {
        get { return selectedLift; }
        set
        {
            if (selectedLift != value)
            {
                selectedLift = value;
                RaisePropertyChanged("SelectedLift");
            }
        }
    }
}

<ListBox ItemsSource="{Binding Mountains}" SelectedItem="{Binding SelectedMountain, Mode=TwoWay}">
<ListBox ItemsSource="{Binding SelectedMountain.Lifts}" SelectedItem="{Binding SelectedMountain.SelectedLift, Mode=TwoWay}">
<ListBox ItemsSource="{Binding SelectedMountain.SelectedLift.Runs}" SelectedItem="{Binding SelectedMountain.SelectedLift.SelectedRun, Mode=TwoWay}">
public类MainViewModel:ViewModelBae
{
可观测集合山
公共可观测采集山
{
获取{返回山;}
设置
{
if(山脉!=值)
{
山=价值;
RaiseProperty变更(“山脉”);
}
}
}
MountainViewModel selectedMountain
公共MountainViewModel SelectedMountain
{
获取{return selectedMountain;}
设置
{
如果(selectedMountain!=值)
{
selectedMountain=值;
RaisePropertyChanged(“SelectedMountain”);
}
}
}
}
公共类MountainViewModel:ViewModelBae
{
可观测收集升降机
公众可看见的集合升降机
{
获取{返回电梯;}
设置
{
如果(提升!=值)
{
提升=价值;
提升性能改变(“提升”);
}
}
}
LiftViewModel SELECTED LIFT
公共电梯视图模式选择电梯
{
获取{return selectedLift;}
设置
{
如果(selectedLift!=值)
{
选择提升=数值;
RaiseProperty已更改(“SelectedLift”);
}
}
}
}
公共类LiftViewModel:ViewModelBae
{
可观察收集运行
公共可观测收集运行
{
获取{返回运行;}
设置
{
如果(运行!=值)
{
运行=值;
RaisePropertyChanged(“运行”);
}
}
}
字符串选择运行
公共字符串SelectedRun
{
获取{return selectedLift;}
设置
{
如果(selectedLift!=值)
{
选择提升=数值;
RaiseProperty已更改(“SelectedLift”);
}
}
}
}

您可能想了解绑定中使用“/”的情况。请参阅本节的“当前项目指针”

以下是我的解决方案:

Xaml


C#(注意,除非属性将被更改,而不仅仅是选择,否则不需要实现INotifyPropertyChanged)

public class MountainsViewModel
{
公共山景模型()
{
山脉=新的可观测集合
{
新山
{
Name=“Whistler”,
提升=新的可观察收集
{
新电梯
{
Name=“大红”,
运行=新的ObservableCollection
{
“端墙”,
“鱼眼”,
“吉米的”
}
},
新电梯
{
Name=“Garbanzo”,
运行=新的ObservableCollection
{
“进展1”,
“鱼眼1”,
“吉米的1”
}
},
新电梯{Name=“Orange”},
}
},
新山
{
Name=“史蒂文斯”,
提升=新的可观察收集
{
新电梯{Name=“One”},
新电梯{Name=“Two”},
新电梯{Name=“Three”},
}
},
public class MainViewModel: ViewModelBae
{
    ObservableCollection<MountainViewModel> mountains
    public ObservableCollection<MountainViewModel> Mountains
    {
        get { return mountains; }
        set
        {
            if (mountains != value)
            {
                mountains = value;
                RaisePropertyChanged("Mountains");
            }
        }
    }
    MountainViewModel selectedMountain
    public MountainViewModel SelectedMountain
    {
        get { return selectedMountain; }
        set
        {
            if (selectedMountain != value)
            {
                selectedMountain = value;
                RaisePropertyChanged("SelectedMountain");
            }
        }
    }
}

public class MountainViewModel: ViewModelBae
{
    ObservableCollection<LiftViewModel> lifts
    public ObservableCollection<LiftViewModel> Lifts
    {
        get { return lifts; }
        set
        {
            if (lifts != value)
            {
                lifts = value;
                RaisePropertyChanged("Lifts");
            }
        }
    }
    LiftViewModel selectedLift
    public LiftViewModel SelectedLift
    {
        get { return selectedLift; }
        set
        {
            if (selectedLift != value)
            {
                selectedLift = value;
                RaisePropertyChanged("SelectedLift");
            }
        }
    }
}

public class LiftViewModel: ViewModelBae
{
    ObservableCollection<string> runs
    public ObservableCollection<string> Runs
    {
        get { return runs; }
        set
        {
            if (runs != value)
            {
                runs = value;
                RaisePropertyChanged("Runs");
            }
        }
    }
    string selectedRun
    public string SelectedRun
    {
        get { return selectedLift; }
        set
        {
            if (selectedLift != value)
            {
                selectedLift = value;
                RaisePropertyChanged("SelectedLift");
            }
        }
    }
}

<ListBox ItemsSource="{Binding Mountains}" SelectedItem="{Binding SelectedMountain, Mode=TwoWay}">
<ListBox ItemsSource="{Binding SelectedMountain.Lifts}" SelectedItem="{Binding SelectedMountain.SelectedLift, Mode=TwoWay}">
<ListBox ItemsSource="{Binding SelectedMountain.SelectedLift.Runs}" SelectedItem="{Binding SelectedMountain.SelectedLift.SelectedRun, Mode=TwoWay}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBlock Margin="5" Grid.Row="0" Grid.Column="0" Text="Mountains"/>
    <TextBlock Margin="5" Grid.Row="0" Grid.Column="1" Text="Lifts"/>
    <TextBlock Margin="5" Grid.Row="0" Grid.Column="2" Text="Runs"/>

    <ListBox Grid.Row="1" Grid.Column="0" Margin="5" 
             ItemsSource="{Binding Mountains}" DisplayMemberPath="Name" 
             IsSynchronizedWithCurrentItem="True" />

    <ListBox Grid.Row="1" Grid.Column="1" Margin="5" 
             ItemsSource="{Binding Mountains/Lifts}" DisplayMemberPath="Name" 
             IsSynchronizedWithCurrentItem="True"/>

    <ListBox Grid.Row="1" Grid.Column="2" Margin="5" 
             ItemsSource="{Binding Mountains/Lifts/Runs}" 
             IsSynchronizedWithCurrentItem="True" 
             SelectedItem="{Binding SelectedRun}"/>
</Grid>
public class MountainsViewModel
{
    public MountainsViewModel()
    {
        Mountains = new ObservableCollection<Mountain>
                        {
                            new Mountain
                                {
                                    Name = "Whistler",
                                    Lifts = new ObservableCollection<Lift>
                                                {
                                                    new Lift
                                                        {
                                                            Name = "Big Red",
                                                            Runs = new ObservableCollection<string>
                                                                       {
                                                                           "Headwall",
                                                                           "Fisheye",
                                                                           "Jimmy's"
                                                                       }
                                                        },
                                                    new Lift
                                                        {
                                                            Name = "Garbanzo",
                                                            Runs = new ObservableCollection<string>
                                                                       {
                                                                           "Headwall1",
                                                                           "Fisheye1",
                                                                           "Jimmy's1"
                                                                       }
                                                        },
                                                    new Lift {Name = "Orange"},
                                                }

                                },
                            new Mountain
                                {
                                    Name = "Stevens",
                                    Lifts = new ObservableCollection<Lift>
                                                {
                                                    new Lift {Name = "One"},
                                                    new Lift {Name = "Two"},
                                                    new Lift {Name = "Three"},
                                                }

                                },
                            new Mountain {Name = "Crystal"},
                        };
    }

    public string Name { get; set; }
    private string _selectedRun;
    public string SelectedRun
    {
        get { return _selectedRun; }
        set
        {
            Debug.WriteLine(value);
            _selectedRun = value;
        }
    }

    public ObservableCollection<Mountain> Mountains { get; set; }
}

public class Mountain
{
    public string Name { get; set; }

    public ObservableCollection<Lift> Lifts { get; set; }
}

public class Lift
{
    public string Name { get; set; }

    public ObservableCollection<string> Runs { get; set; }
}