【问题标题】:UWP C# MVVM How To Access ViewModel from Other PageUWP C# MVVM 如何从其他页面访问 ViewModel
【发布时间】:2020-12-10 03:51:59
【问题描述】:

我想通过一些示例场景进一步了解 MVVM。我有一个rootpage 和一个“主显示器”textblock。我想通过激活任何形式的 UI 来显示“状态”或“场景”,例如。 togglebutton 在“主显示器”上textblock

我可以将rootpageviewmodel 中的页面导航信息绑定到textblock。但是,当显示来自不同页面的信息时,我无法获得结果。 我检查了另一篇帖子 multiple-viewmodels-in-same-viewAccessing a property in one ViewModel from another 它非常相似,但它不起作用。

请帮忙。谢谢。

在访问RootPageViewModel时应该保留实例吗?

查看

<TextBlock Text="{x:Bind RootViewModel.MainStatusContent, Mode=OneWay}"/>

RootPage.xaml.cs

        public sealed partial class RootPage : Page
        {
            private static RootPage instance;
            public RootPageViewModel RootViewModel { get; set; }
    
            public RootPage()
            {
                RootViewModel = new RootPageViewModel();
    
                this.InitializeComponent();
    
                // Always use the cached page
                this.NavigationCacheMode = NavigationCacheMode.Required;
            }
    
            public static RootPage Instance
            {
                get
                {
                    if (instance == null)
                    {
                        instance = new RootPage();
                    }
                    return instance;
                }
            }
         private void nvTopLevelNav_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
            {
                if (args.IsSettingsInvoked)
                {
                    contentFrame.Navigate(typeof(SettingsPage));
    
                    RootViewModel.MainStatusContent = "Settings_Page";
                }
                else
                { 
                    var navItemTag = args.InvokedItemContainer.Tag.ToString();        
                    
                    RootViewModel.MainStatusContent = navItemTag;
                                     
                    switch (navItemTag)
                    {
                        case "Home_Page":   
                            contentFrame.Navigate(typeof(HomePage));
                            break;
    
                        case "Message_Page":  
                            contentFrame.Navigate(typeof(MessagePage));
                            break;
                    }
                    
                }
             }
        }
        

RootPage ViewModel

public class RootPageViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private static RootPageViewModel instance = new RootPageViewModel();
    public static RootPageViewModel Instance
    {
        get
        {
            if (instance == null)
                instance = new RootPageViewModel();

            return instance;
        }
    }

    public RootPageViewModel()
    {
    }

    private string _mainStatusContent;
    public string MainStatusContent
    {
        get
        {
            return _mainStatusContent;
        }
        set
        {
            _mainStatusContent = value;
            OnPropertyChanged();
        }
    }

    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

MessagePage.xaml.cs - 访问 RootPage ViewModel

public sealed partial class MessagePage : Page
{
    public MessagePageViewModel MessageViewModel { get; set; }

    public MessagePage()
    {
        MessageViewModel = new MessagePageViewModel();

        this.InitializeComponent();

        // Always use the cached page
        this.NavigationCacheMode = NavigationCacheMode.Required;
    }

    private void Message1_Checked(object sender, RoutedEventArgs e)
    {
        RootPageViewModel.Instance.MainStatusContent = "Message 1 Selected";
    }

    private void Message1_Unchecked(object sender, RoutedEventArgs e)
    {
        RootPageViewModel.Instance.MainStatusContent = "Message 1 De-Selected";
    }
}

当我调试时,值确实写入了实例,但没有更新TextBlock。我在XAML 绑定中做错了吗?

【问题讨论】:

    标签: c# mvvm uwp navigation


    【解决方案1】:

    UWP C# MVVM 如何从其他页面访问 ViewModel

    更好的方法是为 RootPage 制作静态变量,而不是为 RootPageRootPageViewModel 制作单例实例。

    例如:

    public RootPage ()
    {
        this.InitializeComponent();
        this.NavigationCacheMode = NavigationCacheMode.Required;
        Instance = this;
        RootViewModel = new RootPageViewModel();
    }
    
    public static RootPage Instance;
    

    用法

    private void Message1_Checked(object sender, RoutedEventArgs e)
    {
    
        RootPage.Instance.RootViewModel.MainStatusContent = "Message 1 Selected";
    }
    
    private void Message1_Unchecked(object sender, RoutedEventArgs e)
    {
        RootPage.Instance.RootViewModel.MainStatusContent = "Message 1 De-Selected";
    }
    

    【讨论】:

    • 通过使根页面static 意味着它将始终引用同一个实例?
    • 是的,因为根页面总是在当前窗口的内容中,所以做静态的意思就是它会一直引用到同一个实例
    • 如果不是rootpage 怎么办...它是messagepage 同一级别的另一个页面...我需要singleton
    • 你可以使用单例,为了检查你的代码,我发现你没有使用单例实例。例如用RootViewModel = RootPageViewModel.Instance;替换RootViewModel = new RootPageViewModel();
    • 注明。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多