BindableBase - SetProperty无法使用ViewModel

时间:2015-10-09 22:42:20

标签: c# wpf mvvm prism

我正在尝试使用LoginViewModel中的MainViewModel实例从LoginViewModel设置MainViewModel的属性。但XAML中的绑定不会得到通知!我在MainViewModel中设置断点,它显示正在设置的值,但是如果它通过实例设置它不起作用。有人可以帮忙吗? 以下是两个viewmodel的代码。如您所见,在我的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>

2 个答案:

答案 0 :(得分:1)

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

另一个您在viewmodel中创建一个单独的静态对象并通过Instance属性公开。

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

答案 1 :(得分:0)

在ModelViews之间实现通信的最佳方式似乎是使用prism Event Aggregation!

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