我在MVVM WPF应用程序中引用不同用户控件上的属性或元素时遇到问题。
编辑:将代码简化为MCVE(希望如此)。还删除了PropertyChanged事件以减少代码。
如何使用MVVM方法(最好是作为MenuBar上的CommandParameter)从PasswordBox中检索值?
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
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:ViewModel="clr-namespace:WpfApp1.ViewModel"
xmlns:View="clr-namespace:WpfApp1.View"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<ViewModel:SettingsViewModel/>
</Window.DataContext>
<StackPanel>
<DockPanel>
<View:MenuBar DataContext="{Binding}"/>
</DockPanel>
<TabControl>
<TabItem Header="Tab1" DataContext="{Binding AppSettings}">
<View:TabItemContent/>
</TabItem>
</TabControl>
</StackPanel>
</Window>
应该绑定到ViewModel(MainWindow的DataContext)的ICommand属性上的MenuBar。
MenuBar.xaml
<UserControl x:Class="WpfApp1.View.MenuBar"
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:local="clr-namespace:WpfApp1.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" >
<Menu DockPanel.Dock="Top" Height="Auto" >
<!-- In the command I need a reference to the password on the tabItem -->
<MenuItem Name="SaveItem" Height="Auto" Header="Save"
Command="{Binding SaveCommand}"
CommandParameter="Binding RelativeSource=
{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>
</Menu>
</UserControl>
TabItemContent.xaml
<UserControl x:Class="WpfApp1.View.TabItemContent"
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:local="clr-namespace:WpfApp1.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
DataContext="{Binding PasswordSettings}">
<Grid>
<PasswordBox Height="25" Width="100" />
</Grid>
</UserControl>
在 TabItemControl.xaml.cs 中,我试图引入依赖项属性并将其值设置为控件的数据上下文。
SettingViewModel.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using WpfApp1.Commands;
using WpfApp1.Model;
namespace WpfApp1.ViewModel
{
public class SettingsViewModel
{
public Settings AppSettings { get; private set; } = new Settings();
public ICommand SaveCommand { get; private set; }
public SettingsViewModel()
{
SaveCommand = new DelegateCommand( SaveSettings );
// load settings and call
// OnPropertyChanged( "AppSettings" );
}
public void SaveSettings( object o = null )
{
if( o is string encryptedPass )
{
// get the password and save it to AppSettings object
}
// call save method on settings
}
}
}
AppSetting.cs (封装了其他标签中的所有设置对象)
namespace WpfApp1.Model
{
public class Settings
{
public PasswordSettings PwSettings { get; set; } = new PasswordSettings();
}
}
PasswordSettings.cs
namespace WpfApp1.Model
{
public class PasswordSettings
{
public string EncryptedPass { get; set; }
}
}
最后是
中的DelegateCommand
实现
DelegateCommand.cs 参见this gist