BindableBase - SetProperty 无法使用 ViewModel 的实例

BindableBase - SetProperty does not work using the instance of the ViewModel

我正在尝试使用 LoginViewModel 中的 MainViewModel 实例从 LoginViewModel 设置 MainViewModel 的 属性。但是 XAML 中的绑定没有得到通知!我在 MainViewModel 中设置了断点,它显示正在设置值,但如果它通过实例设置则不起作用。谁能帮忙? 下面是两个视图模型的代码。如您所见,在我的登录视图模型中,我使用 MainViewModel 的实例设置 public 属性 :

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;
            }

    }

登录视图模型

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 解析器在遇到设置数据上下文的代码时构造的。

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

您需要一种不同的方式来在 ViewModel 实例之间进行通信。 Prism 中的 Pub-Sub 事件是处理这种情况的最佳方式,尽管使用 CompositeCommand 也可以。

似乎实现 ModelView 之间通信的最佳方式是使用 prism 事件聚合!

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