简体   繁体   English

使用MVVM Light绑定到Windows Phone 8.1中的伪静态数据

[英]Binding to pseudo-static data in Windows Phone 8.1 with MVVM Light

Desired Result 所需结果

  • A status bar at the top of most xaml pages, of which the colour and text change depending on the value of a boolean variable. 大多数xaml页面顶部的状态栏,其颜色和文本根据布尔变量的值而变化。
  • The page background is also set to a colour based on this boolean. 页面背景也基于此布尔值设置为颜色。
  • Essentially these signify whether the app is connected to the server; 本质上,这些表示应用程序是否已连接到服务器; we don't need to discuss connectivity logic here, apart from a method which inverts the "online" boolean, so as to simulate changing connectivity status and to test the bindings. 除了反转“在线”布尔值的方法之外,我们不需要在这里讨论连接逻辑,以便模拟变化的连接状态并测试绑定。
  • I want these to update without repeated logic in every view model. 我希望这些更新在每个视图模型中都没有重复的逻辑。

Current Implementation 当前实施

To try and minimise the amount of code, I will try to reduce the project into four files, and also only concern ourselves with the text property (if we can get text working, we can get colour working too). 为了尽量减少代码量,我将尝试将项目缩减为四个文件,并且仅关注text属性(如果可以使文本工作,也可以使颜色工作)。 Hopefully we can assume my ViewModelLocator.cs, App.xaml, Generic.xaml and the supporting ConnectivityStatusBar.cs have been correctly implemented (I can share these too if necessary). 希望我们可以假设我的ViewModelLocator.cs,App.xaml,Generic.xaml和支持的ConnectivityStatusBar.cs已正确实现(必要时我也可以共享)。

  • HomePage.xaml: An example view which utilises the connectivity status bar. HomePage.xaml:使用连接状态栏的示例视图。
<Page
    x:Class="Client.View.HomePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:customElements="using:Client.CustomElements"
    mc:Ignorable="d"
    DataContext="{Binding Source={StaticResource ViewModelLocator}}">

    <Grid>
        <StackPanel>
            <customElements:ConnectivityStatusBar
                Text="{Binding ConnectivityStatusBar.Text,
                      Source={StaticResource ViewModelLocator}}" />
            <Button Content="Invert"
                    Command="{Binding HomePage.InvertConnectivityCommand}" />
        </StackPanel>
    </Grid>
</Page>
  • SessionData.cs: Where the connectivity boolean is found, I have tried setting the class up like a singleton. SessionData.cs:在找到连接布尔值的地方,我尝试将类设置为单例。
using Client.ViewModel;
using GalaSoft.MvvmLight;

namespace Client
{
    public sealed class SessionData : ViewModelBase
    {
        private static readonly SessionData Instance = new SessionData();
        private bool _online;

        public static SessionData getInstance
        {
            get { return Instance; }
        }

        public bool Online
        {
            get { return _online; }
            set
            {
                _online = value;
                RaisePropertyChanged(() => Online);
                RaisePropertyChanged(() => ConnectivityStatusBarViewModel.getInstance.Text);
            }
        }
    }
}
  • ConnectivityStatusBarViewModel.cs: Logic deciding what the colour and text for the status bar should be. ConnectivityStatusBarViewModel.cs:确定状态栏的颜色和文本应为逻辑。 I have attempted similar singleton logic here. 我在这里尝试过类似的单例逻辑。
using System;
using GalaSoft.MvvmLight;

namespace Client.ViewModel
{
    public sealed class ConnectivityStatusBarViewModel : ViewModelBase
    {
        private static readonly ConnectivityStatusBarViewModel Instance = new ConnectivityStatusBarViewModel();

        public static ConnectivityStatusBarViewModel getInstance
        {
            get { return Instance; }
        }

        public String Text
        {
            get { return SessionData.getInstance.Online ? "Online" : "Offline"; }
        }
    }
}
  • HomePageViewModel.cs: Where the boolean inversion method is found. HomePageViewModel.cs:找到布尔反转方法的位置。
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

namespace Client.ViewModel
{
    public class HomePageViewModel : ViewModelBase
    {
        public HomePageViewModel()
        {
            InvertConnectivityCommand = new RelayCommand(InvertConnectivity);
        }

        public RelayCommand InvertConnectivityCommand { get; set; }

        private void InvertConnectivity()
        {
            SessionData.getInstance.Online = !SessionData.getInstance.Online;
        }
    }
}

This code doesn't give me the results I want; 这段代码没有给我想要的结果; when the button is pressed on HomePage.xaml, the text does not change. 当在HomePage.xaml上按下按钮时,文本不会更改。 It does work if I put the inversion method into ConnectivityStatusBarViewModel.cs. 如果将反转方法放入ConnectivityStatusBarViewModel.cs中,它将起作用。

Is it possible to make this work, or am I wasting my time? 是否可以进行这项工作,还是我在浪费时间? If it is possible, how can I change my approach to make it work? 如果有可能,我如何更改我的方法以使其起作用?

Edit : ViewModelLocator.cs looks like: 编辑 :ViewModelLocator.cs看起来像:

using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;

namespace Client.ViewModel
{
    public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            SimpleIoc.Default.Register<ConnectivityStatusBarViewModel>();
            SimpleIoc.Default.Register<HomePageViewModel>();
        }

        public ConnectivityStatusBarViewModel ConnectivityStatusBar
        {
            get { return ServiceLocator.Current.GetInstance<ConnectivityStatusBarViewModel>(); }
        }

        public HomePageViewModel HomePage
        {
            get { return ServiceLocator.Current.GetInstance<HomePageViewModel>(); }
        }
    }
}

Instead of registering new ConnectivityStatusBarViewModel instance in ViewModelLocator, can you try providing the exact instance to it. 您可以尝试向其提供确切的实例,而不是在ViewModelLocator中注册新的ConnectivityStatusBarViewModel实例。

SimpleIoc.Default.Register(() => ConnectivityStatusBarViewModel.getInstance);

This way when the call to get the instance gets invoked: 这样,当获取实例的调用被调用时:

return ServiceLocator.Current.GetInstance<ConnectivityStatusBarViewModel>();

you will actually be returning that instance. 您实际上将返回该实例。

So when you do binding to VMlocator and ConnectivityStatusBar.Text, it should work. 因此,当您绑定到VMlocator和ConnectivityStatusBar.Text时,它应该可以工作。

Text="{Binding ConnectivityStatusBar.Text,
       Source={StaticResource ViewModelLocator}}" 

You were essentially binding to another instance, which is why the data wasn't refreshed in the UI. 您实际上是在绑定到另一个实例,这就是为什么未在UI中刷新数据的原因。

BTW there are some design issues/redundancies with this/your code, but it's out of the scope of the question - I am trying to make minimal changes to it to get it working. 顺便说一句,此代码/您的代码存在一些设计问题/冗余,但这超出了问题的范围-我正尝试对其进行最小的更改以使其正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM