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