使用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>

使用ViewModel的实例时,BindableBase - SetProperty不起作用

您正在处理MainViewModel的两个不同实例。实际连接到视图的那个是由XAML解析器在遇到设置数据上下文的代码时构造的。

另一个在视图模型中创建为单独的静态对象,并通过Instance属性公开。

您需要一种不同的方式在ViewModel实例之间进行通信。Prism中的发布-订阅事件是处理此类场景的最佳方式,尽管使用CompositeCommand也可以工作。

似乎实现ModelViews之间通信的最好方法是使用prism事件聚合!

在MSDN上提供了一个示例:https://msdn.microsoft.com/en-us/library/ff921173(v=pandp.40).aspx