wpf - 具有多个用户控件级别的属性的 WPF 绑定
问题描述
我有两个用户控件(LoginView.xaml 和 DashboardView.xaml)。DashboardView.xaml 放置在 LoginView.xaml 中。现在,我的目标最初是 DashboardView 应该是不可见的,登录成功后它应该是可见的,并且堆栈面板“loginSP”中的控件应该是不可见的。
LoginView.xaml 如下:-
<UserControl x:Class="DashboardModule.LoginView"
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:DashboardModule"
xmlns:converter="clr-namespace:Matrix.Infrastructure.Framework.Utility;assembly=Matrix.Infrastructure"
mc:Ignorable="d"
x:Name="loginUC"
d:DesignHeight="450" d:DesignWidth="800" Background="Pink">
<UserControl.Resources>
<ResourceDictionary>
<converter:BooleanToVisibilityConverter x:Key="BoolVisibilityConverter"></converter:BooleanToVisibilityConverter>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel Margin="200">
<StackPanel x:Name="loginSP">
<TextBlock Text="Dashboard" ></TextBlock>
<TextBox x:Name="tbUserName" Height="25" Width="300" ></TextBox>
<PasswordBox Margin="2"></PasswordBox>
<Button Content="Login" Command="{Binding LoginCommand}" CommandParameter="{Binding Path=Text,ElementName=tbUserName}" Width="200"
></Button>
</StackPanel>
<ContentControl>
<ContentControl.Template>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Grid>
<Border >
<ContentPresenter/>
</Border>
</Grid>
</ControlTemplate>
</ContentControl.Template>
<local:DashboardView Visibility="{Binding DashboardVisible, Converter={StaticResource BoolVisibilityConverter}}"/>
</ContentControl>
</StackPanel>
DashboardView.xaml 如下:-
<UserControl x:Class="DashboardModule.DashboardView"
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:DashboardModule"
xmlns:converter="clr-namespace:Matrix.Infrastructure.Framework.Utility;assembly=Matrix.Infrastructure"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Background="BlanchedAlmond" x:Name="DashboardUC"
Visibility="{Binding Visibility,ElementName=rootGrd}">
<UserControl.Resources>
<ResourceDictionary>
<converter:BooleanToVisibilityConverter x:Key="BoolVisibilityConverter"></converter:BooleanToVisibilityConverter>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="rootGrd" ToolTip="{Binding MyName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding DashboardVisible,Converter={StaticResource BoolVisibilityConverter}}">
<TextBlock Text="{Binding MyName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
</Grid>
我的 LoginViewModel.cs 如下:-
private readonly IEventAggregator eventAggregator;
public DelegateCommand<string> LoginCommand { get; set; }
public DashboardViewModel DashborardVM { get; set; }
public LoginViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
DashborardVM = new DashboardViewModel();
LoginCommand = new DelegateCommand<string>(Login, IsValid);
}
private void Login(string obj)
{
DashborardVM.MyName = "My Name After Login";
DashborardVM.DashboardVisible = true;
//this.eventAggregator.GetEvent<ShellLayoutChangeEvent>().Publish("anindya");
}
private bool IsValid(string param)
{
if (param.Length > 0)
我的 DashboardViewModel.cs 代码如下:-
private bool _dashboardVisible;
public bool DashboardVisible
{
get
{
return _dashboardVisible;
}
set
{
_dashboardVisible = value;
OnPropertyChanged("DashboardVisible");
}
}
private string myName;
public string MyName
{
get
{
return myName;
}
set
{
myName = value;
OnPropertyChanged("MyName");
}
}
public DashboardViewModel()
{
MyName = "anindya";
}
现在的输出是: 1.Initially DashboardView 是不可见的。2. 登录成功后,尽管我设置了 DashborardVM.DashboardVisible = true,但 DashboardView 不可见;在我的 loginviewmode.cs 上。
我正在使用棱镜设计模式。以下方式我正在注册视图和视图模型。
public class ModuleDashboardModule: IModule
{
IUnityContainer _container;
IRegionManager _regionManager;
public ModuleDashboardModule(IUnityContainer container,
IRegionManager regionManager)
{
_container = container;
_regionManager = regionManager;
}
public void Initialize()
{
_container.RegisterType<ILoginView, LoginView>();
_container.RegisterType<ILoginViewModel, LoginViewModel>();
_container.RegisterType<IDashboardView, DashboardView>();
_container.RegisterType<IDashboardViewModel, DashboardViewModel>();
_regionManager.RegisterViewWithRegion(RegionNames.DashboardRegion,
typeof(LoginView));
_regionManager.RegisterViewWithRegion(RegionNames.DashboardRegion,
typeof(DashboardView));
}
}
这是我的 bootstrapper.cs 类:--
public class BootStrapper : UnityBootstrapper,IDisposable
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)Shell;
App.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
Type moduleAType = typeof(ModuleDetailsModule);
Type moduleNewForm = typeof(ModuleNewFormModule);
Type moduleToolbarType = typeof(ModuleToolbarModule);
Type moduleFooterType = typeof(ModuleFooterModule);
Type moduleDashboardType = typeof(ModuleDashboardModule);
Type moduleInvestmentType = typeof(ModuleInvestmentModule);
Type moduleInvestmentDetailsType = typeof(ModuleInvestmentDetailsModule);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleAType.Name,
ModuleType = moduleAType.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleNewForm.Name,
ModuleType = moduleNewForm.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleToolbarType.Name,
ModuleType = moduleToolbarType.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleFooterType.Name,
ModuleType = moduleFooterType.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleDashboardType.Name,
ModuleType = moduleDashboardType.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleInvestmentType.Name,
ModuleType = moduleInvestmentType.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
ModuleCatalog.AddModule
(
new ModuleInfo()
{
ModuleName = moduleInvestmentDetailsType.Name,
ModuleType = moduleInvestmentDetailsType.AssemblyQualifiedName,
InitializationMode = InitializationMode.WhenAvailable
}
);
}
我的 LoginView.xaml.cs 文件是:
public partial class LoginView : UserControl,ILoginView
{
[InjectionConstructor]
public LoginView(LoginViewModel viewModel)
{
InitializeComponent();
this.ViewModel = viewModel;
}
public IViewModel ViewModel
{
get
{
return (IViewModel)DataContext;
}
set
{
DataContext = value;
}
}
}
我的 DashboardView.xaml.cs 如下:
public partial class DashboardView : UserControl,IDashboardView
{
DashboardViewModel viewModel = new DashboardViewModel();
[InjectionConstructor]
public DashboardView()
{
InitializeComponent();
this.DataContext = viewModel;
//this.ViewModel = viewModel;
}
public IViewModel ViewModel
{
get
{
return (IViewModel)DataContext;
}
set
{
DataContext = value;
}
}
}
我没有得到我犯错的地方。任何帮助都是可观的。
解决方案
这都是关于设置正确的数据上下文。
似乎您没有为仪表板视图设置数据上下文。因此 loginViewModel 成为仪表板视图的数据上下文。这是因为如果未显式设置,数据上下文将从 xaml 的父控件继承。
尝试为内容控制设置数据上下文
<ContentControl DataContext="{Binding DashborardVM}">
<ContentControl.Template>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Grid>
<Border >
<ContentPresenter/>
</Border>
</Grid>
</ControlTemplate>
</ContentControl.Template>
<local:DashboardView Visibility="{Binding DashboardVisible, Converter={StaticResource BoolVisibilityConverter}}"/>
</ContentControl>
否则,您将不得不以格式进行所有绑定
{Binding DashborardVM.DashboardVisible}
{Binding DashborardVM.property}
编辑-顺便说一句,如果您使用的是棱镜,请检查视图模型是否已正确注册,以便它们自动分配。并且可能将可见性设置为
<local:DashboardView Visibility="{Binding DashborardVM.DashboardVisible, Converter={StaticResource BoolVisibilityConverter}}"/>
会有所帮助,因为这里的数据上下文是 LoginViewmodel
推荐阅读
- javascript - 在 fastify 中修改或保存请求对象中的数据
- baidu-map - 在百度地图上显示路线,开始/结束编码在 url
- java - 从 SQL 创建 ElasticSearch 6.5 嵌套布尔查询
- android - 改造 POST 请求永远不会返回到 OnResponse
- wordpress - Wordpress 中的乳胶表示法
- r - R Caret createFolds 不均匀
- angular - ngxs 异步操作的成功/失败操作事件的目的是什么?
- wpf - 折叠时其他人未使用WPF用户控件空间
- javascript - window.open() 跟踪用户输入
- windows - 如何在命令提示符下将整个输出发送到日志文件以显示时间更改和错误