问题描述
我是 WPF 的新手,我只是用 MVVM 和 bindings 和 commands 做一个简单的菜单> 但我认为我做错了什么.我只想在每次按下菜单按钮时更改所有导入我定义的新 UserControl
的窗口内容.这意味着我想消失菜单并显示一个新内容(我之前提到的 UserControls).
I'm new with WPF and I was just doing a simple menu using MVVM with bindings and commands but I think I'm doing something wrong. I just want to change all the Window Content importing a new UserControl
I defined, everytime I press a Menu Button. That means I want to disappear the menu and show a new content (the UserControls I mentioned before).
我有主窗口(控制面板):
<Window x:Class="OfficeMenu.Views.Menu.ControlPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Control Panel" Height="800" Width="800">
<Grid>
<ContentControl Content="{Binding contentWindow}"/>
</Grid>
</Window>
这是 UserControls 之一,它在我运行项目时向主窗口提供按钮菜单:
This one of the UserControls that provides a Menu of buttons to the Main Window when I run the project:
<UserControl x:Class="OfficeMenu.Views.ButtonsMenu"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<!-- One style for each *type* of control on the window -->
<Style TargetType="Button">
<Setter Property="Margin" Value="5"/>
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Button Command="{Binding OpenUsersCommand}">BUTTON 1</Button>
<Button Grid.Column="1">BUTTON 2</Button>
<Button Grid.Column="1" Grid.Row="2" >BUTTON 3</Button>
<Button Grid.Row="1">BUTTON 4</Button>
</Grid>
</UserControl>
这是我使用的 ViewModel:
class MenuViewModel : ViewModelBase
{
RandomModel _model; <!-- It does nothing important -->
private UserControl _content;
public ICommand OpenUsersCommand { get; private set; }
public UserControl Content
{
get { return _content; }
set {
_content = value;
NotifyPropertyChanged("contentWindow");
}
}
public MenuViewModel(RandomModel model )
{
this._model= model;
OpenUsersCommand = new RelayCommand(OpenUsers,null);
}
private void OpenUsers()
{
Content = new UsersPanel(); //This is the UserControl we need to load dinamically
}
}
在 App.xaml.cs 我们加载主窗口:
In App.xaml.cs we load the main window:
public partial class App : Application
{
private void OnStartup(object sender, StartupEventArgs e)
{
ControlPanel view = new ControlPanel();
view.ShowDialog();
}
}
现在,controlPanel.xaml.cs:
Now, the controlPanel.xaml.cs:
public ControlPanel()
{
InitializeComponent();
ModelRandom model = new ModelRandom(); <!-- It does nothing yet -->
MenuViewModel viewmodel = new MenuViewModel(model);
Content = new BottonsMenu(); <!-- We load a default UserControl when we run the program -->
this.DataContext = viewmodel;
}
}
非常感谢.
推荐答案
我认为问题在于您试图更改 ContentControl 的 Content 属性,而不是 ViewModel 的属性.您已将 ViewModel 连接到主机 ControlPanel,但您还需要单独的视图模型用于将托管在那里的用户控件.为了清楚起见,我为用户控件视图模型添加了类并更改了主机的视图模型属性名称.更正您的代码如下.
I think the problem is that you are trying to change the Content property of ContentControl, not the property of your ViewModel. You have connected your ViewModel to the host ControlPanel, but also you need the separate view models for user controls that will be hosted there. I've added class for user control view model and changed host's view model property name for the clarity sake. Correct your code as follows.
//host view model
class MainModel : ViewModelBase
{
private UserControl _content;
public MainModel() { }
internal void SetNewContent(UserControl _content)
{
ContentWindow = _content;
}
public UserControl ContentWindow
{
get { return _content; }
set
{
_content = value;
OnPropertyChanged("ContentWindow");
}
}
}
//user contol's view model
class MenuViewModel : ViewModelBase
{
MainModel _mainModel;
RandomModel _model; // <!-- It does nothing important -->
public ICommand OpenUsersCommand { get; private set; }
public MenuViewModel(MainModel mainModel, RandomModel model )
{
this._mainModel = mainModel;
this._model = model;
OpenUsersCommand = new RelayCommand(OpenUsers, CanOpenUsers);
}
private void OpenUsers(object _param)
{
UsersPanelViewModel upmodel = new UsersPanelViewModel(_mainModel, _model);
UsersPanel up = new UsersPanel();
up.DataContext = upmodel;
_mainModel.SetNewContent(up);
}
private bool CanOpenUsers(object _param)
{
return true;
}
}
//main window function
public ControlPanel()
{
InitializeComponent();
//create main view model for host
MainModel mainModel = new MainModel();
RandomModel model = new RandomModel(); //<!-- It does nothing yet -->
//create view model for user controls
MenuViewModel viewmodel = new MenuViewModel(mainModel, model);
ButtonsMenu bm = new ButtonsMenu(); // <!-- We load a default UserControl when we run the program -->
bm.DataContext = viewmodel;
//set host's property in our user control
mainModel.ContentWindow = bm;
this.DataContext = mainModel;
}
主窗口 XAML
<Window x:Class="WpfApplication1.ControlPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ContentControl Content="{Binding ContentWindow}"/>
</Grid>
</Window>
希望它是可以理解的.
这篇关于在 WPF (MVVM) 中动态更改窗口的用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!