pio*_*sco 5 c# xaml user-controls mvvm mvvm-light
我决定使用MVVM Light库来帮助设计UI.经过大量的研究和反复试验,我还没有找到我想要的答案.我用谷歌搜索并阅读了我能找到的每个StackOverflow问题,然而,我的问题似乎在SO上是独一无二的.
我希望设计一个带有单个窗口的UI,并使用不同的Views/UserControls填充它.我不想在UserControls中使用共享导航栏,也不想弹出多个窗口.每个View/UserControl都应绑定到自己的ViewModel,而MainWindow将绑定到MainViewModel.
示例场景 - 具有3个UserControl的MainWindow
1. MainWindow populates with first UserControl which has a listbox and 3 buttons, the first button is enabled.
2. User clicks the first button.
3. MainWindow populates with second UserControl.
Run Code Online (Sandbox Code Playgroud)
或者,另外
2. User selects choice from a listbox, button two and three become available.
3. User clicks second/third button.
4. MainWindow populates with second/third UserControl.
Run Code Online (Sandbox Code Playgroud)
等等
也许我的方法不现实,但我觉得这必须是可能的.我不明白如何让所有这些作品在概念上发挥作用.我的欲望绝不是独一无二的.如果您认为这是重复的问题,请重定向.干杯.
为了使事情更容易理解,我在下面列出了一些课程.首先,我的App.xaml.
<Application x:Class="Bobcat_BETA.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:Bobcat_BETA.UserControls"
xmlns:vm="clr-namespace:Bobcat_BETA.ViewModels"
StartupUri="MainWindow.xaml"
mc:Ignorable="d">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<DataTemplate DataType="{x:Type vm:SavedScenariosViewModel}">
<views:SavedScenariosUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ScenarioEditorViewModel}">
<views:ScenarioEditorUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SimulatorViewModel}">
<views:SimulatorUserControl />
</DataTemplate>
</Application.Resources>
</Application>
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml
<Window x:Class="Bobcat_BETA.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Bobcat - Version:0.00"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid>
<ContentControl Content="{Binding CurrentView}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)
ViewModelLocator.cs
namespace Bobcat_BETA.ViewModels
{
public class ViewModelLocator
{
private static MainViewModel _main;
public ViewModelLocator()
{
_main = new MainViewModel();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return _main;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
MainViewModel.cs
namespace Bobcat_BETA.ViewModels
{
public class MainViewModel : ViewModelBase
{
private ViewModelBase _currentViewModel;
readonly static SavedScenariosViewModel _savedScenarioViewModel = new SavedScenariosViewModel();
readonly static ScenarioEditorViewModel _scenarioEditorViewModel = new ScenarioEditorViewModel();
readonly static SimulatorViewModel _simulatorViewModel = new SimulatorViewModel();
public ViewModelBase CurrentViewModel
{
get
{
return _currentViewModel;
}
set
{
if (_currentViewModel == value)
return;
_currentViewModel = value;
RaisePropertyChanged("CurrentViewModel");
}
}
public MainViewModel()
{
CurrentViewModel = MainViewModel._savedScenarioViewModel;
SavedScenarioViewCommand = new RelayCommand(() => ExecuteSavedScenarioViewCommand());
ScenarioEditorViewCommand = new RelayCommand(() => ExecuteScenarioEidtorViewCommand());
SimulatorViewCommand = new RelayCommand(() => ExecuteSimulatorViewCommand());
}
public ICommand SavedScenarioViewCommand { get; private set; }
public ICommand ScenarioEditorViewCommand { get; private set; }
public ICommand SimulatorViewCommand { get; private set; }
private void ExecuteSavedScenarioViewCommand()
{
CurrentViewModel = MainViewModel._savedScenarioViewModel;
}
private void ExecuteScenarioEidtorViewCommand()
{
CurrentViewModel = MainViewModel._scenarioEditorViewModel;
}
private void ExecuteSimulatorViewCommand()
{
CurrentViewModel = MainViewModel._simulatorViewModel;
}
}
}
Run Code Online (Sandbox Code Playgroud)
SavedScenariosViewModel.cs
namespace Bobcat_BETA.ViewModels
{
public class SavedScenariosViewModel : ViewModelBase
{
public SavedScenariosViewModel()
{
}
ObservableCollection<ScenarioModel> _scenarioModels = new ObservableCollection<ScenarioModel>()
{
new ScenarioModel() {Name = "Scenario 0", ID = 000, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 1", ID = 001, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 2", ID = 002, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 3", ID = 003, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 4", ID = 004, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 5", ID = 005, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 6", ID = 006, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 7", ID = 007, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 8", ID = 008, Desc = "This will describe the Scenario Model."},
new ScenarioModel() {Name = "Scenario 9", ID = 009, Desc = "This will describe the Scenario Model."}
};
public ObservableCollection<ScenarioModel> ScenarioModels
{
get { return _scenarioModels; }
}
}
}
Run Code Online (Sandbox Code Playgroud)
SavedScenariosUserControl.xaml
<UserControl x:Class="Bobcat_BETA.UserControls.SavedScenariosUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:Bobcat_BETA.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Dictionaries/MasterDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.Style>
<DynamicResource ResourceKey="GeneralUserControl"/>
</UserControl.Style>
<Grid>
<Label Content="Saved Scenario Selection"
Style="{StaticResource GeneralLabel}" HorizontalAlignment="Left" Margin="26,30,0,0" VerticalAlignment="Top" Height="62" Width="345"/>
<Label Content="Chose Flight Model:"
Style="{StaticResource GeneralLabel2}"
HorizontalAlignment="Left" Margin="27,111,0,0" VerticalAlignment="Top" Height="43" Width="345"/>
<ListBox Style="{StaticResource GeneralListBox}"
HorizontalAlignment="Left" Height="509" Margin="27,154,0,0" VerticalAlignment="Top" Width="345"
ItemsSource="{Binding ScenarioModels}"/>
<Button Content="New"
Style="{StaticResource TransitionButton}"
HorizontalAlignment="Left" Margin="948,601,0,0" VerticalAlignment="Top" MinHeight="62" MinWidth="150" IsEnabled="True"
Command="{Binding ScenarioEditorViewCommand}"/>
<Button Content="Edit"
Style="{StaticResource TransitionButton}"
HorizontalAlignment="Left" Margin="401,519,0,0" VerticalAlignment="Top" MinHeight="62" MinWidth="150"
Command="{Binding SaveScenariosViewCommand}"/>
<Button Content="Load"
Style="{StaticResource TransitionButton}"
HorizontalAlignment="Left" Margin="401,601,0,0" VerticalAlignment="Top" MinHeight="62" MinWidth="150"
Command="{Binding SimulatorViewCommand}"/>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
如果有什么不清楚的地方,我也可以添加Model类,但我认为你可以根据发生的事情进行推断.谢谢.
所以你的方法是非常合理的。为了获得该功能,您必须使用某些复杂的功能。我必须使用包含所有视图模型的“MainViewModel”。这些视图模型的行为使得当数据上下文切换到不同的视图模型时,相应的用户控件将更改为适当的视图。谢里登在这里回答了我遵循的一个很好的例子。使用适当的数据模板挂钩到您的 app.xaml,数据上下文切换将像魔术一样处理:D
在我偏离 Sheridan 的示例的地方(因为我不想创建单独的中继命令类/对象),我实际上使用 mvvm light (galasoft) 将消息从我的视图模型发送到消息回“MainViewModel”以切换其数据语境。可以在此处找到使用 MVVM 轻型消息传递的一个很好的示例。从“子”视图模型发送消息并将其注册到“MainViewModel”中。
祝你好运!
归档时间: |
|
查看次数: |
6125 次 |
最近记录: |