使用ViewModel的实例时,BindableBase - SetProperty不起作用
本文关键字:BindableBase SetProperty 不起作用 ViewModel 实例 使用 | 更新日期: 2023-09-27 18:17:04
我试图使用LoginViewModel内的MainViewModel的实例从LoginViewModel设置MainViewModel的属性。但是XAML中的绑定没有得到通知!我在MainViewModel中设置了断点,它显示了正在设置的值,但如果通过实例设置,则不工作。有人能帮忙吗?下面是两个视图模型的代码。如您所见,在我的loginviewmodel中,我使用MainViewModel的实例设置了公共属性:
MainViewModel.Instance.Mainviewpageindex = 1;
MainViewModel
namespace DataRetrieval.ViewModels
{
public class MainViewModel : BindableBase
{
private static MainViewModel _instance = new MainViewModel();
public static MainViewModel Instance { get { return _instance; }
}
private int _mainviewpageindex;
public int Mainviewpageindex
{
get {
return _mainviewpageindex; }
set {
SetProperty(ref _mainviewpageindex, value);
// _mainviewpageindex = value;
// RaisePropertyChangedEvent("Mainviewpageindex");
}
}
public MainViewModel()
{
Mainviewpageindex = 0;
}
public DelegateCommand<object> _loginCommand;
public ICommand LoginCommand
{
get
{
_loginCommand = new DelegateCommand<object>(Login, VerifyLogin);
return _loginCommand;
}
}
private void Login(object context)
{
Mainviewpageindex = 1;
}
private bool VerifyLogin(object context)
{
return true;
}
}
LoginViewModel
namespace DataRetrieval.ViewModels
{
public class LoginViewModel : BindableBase
{
// public SecureString SecurePassword { private get; set; }
private string _uname;
public string Uname
{
get { return _uname; }
set {
SetProperty(ref _uname, value);
_loginCommand.RaiseCanExecuteChanged();
}
}
private SecureString _securePassword;
public SecureString SecurePassword
{
get { return _securePassword; }
set {
SetProperty(ref _securePassword, value);
_loginCommand.RaiseCanExecuteChanged();
}
}
public LoginViewModel()
{
}
public DelegateCommand<object> _loginCommand;
public ICommand LoginCommand
{
get
{
_loginCommand = new DelegateCommand<object>(Login, VerifyLogin);
return _loginCommand;
}
}
private void Login(object context)
{
if (SecurePassword != null || Uname != null)
{
//PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// bool validated = ctx.ValidateCredentials(Uname, SecureStringToString(SecurePassword));
MainViewModel.Instance.Mainviewpageindex = 1;
}else
{
}
}
String SecureStringToString(SecureString value)
{
IntPtr valuePtr = IntPtr.Zero;
try
{
valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
return Marshal.PtrToStringUni(valuePtr);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
}
}
private bool VerifyLogin(object context)
{
return true;
}
}
}
XAML: <Window x:Class="DataRetrieval.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:DataRetrieval.Views"
xmlns:prism="http://www.codeplex.com/prism"
xmlns:viewModels="clr-namespace:DataRetrieval.ViewModels"
Title="Data Retrieval Tool" Height="Auto" Width="900" Icon="Resources/colorful_query_mark_light_bulb_28261523_y2o_icon.ico">
<Window.DataContext>
<viewModels:MainViewModel />
</Window.DataContext>
<TabControl Name="TabControl1" BorderBrush="{x:Null}" Background="White" SelectedIndex="{Binding Mainviewpageindex, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</TabControl.ItemContainerStyle>
<TabItem Header="General">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" MaxWidth="300"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="auto" />
<RowDefinition Height="300"/>
</Grid.RowDefinitions>
<views:Login HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" />
<TextBlock TextWrapping="Wrap" TextAlignment="Center" Text="User your OneAbbott domain user name and password to login into the system" Grid.Column="1" Grid.Row="2"/>
<Button x:Name="btnLogin" Content="Login" Margin="20" Command="{Binding LoginCommand}"/>
</Grid>
</TabItem>
<TabItem Header="Second Tab">
<StackPanel>
<TextBlock TextWrapping="Wrap" TextAlignment="Center" Text="Login Successfull" Grid.Column="1" Grid.Row="2"/>
</StackPanel>
</TabItem>
</TabControl>
</Window>
您正在处理MainViewModel的两个不同实例。实际连接到视图的那个是由XAML解析器在遇到设置数据上下文的代码时构造的。
另一个在视图模型中创建为单独的静态对象,并通过Instance属性公开。
您需要一种不同的方式在ViewModel实例之间进行通信。Prism中的发布-订阅事件是处理此类场景的最佳方式,尽管使用CompositeCommand也可以工作。
似乎实现ModelViews之间通信的最好方法是使用prism事件聚合!
在MSDN上提供了一个示例:https://msdn.microsoft.com/en-us/library/ff921173(v=pandp.40).aspx