x:UWP应用程序中的绑定和嵌套类

时间:2015-11-06 14:50:50

标签: c# xaml mvvm uwp

我目前正在研究UWP应用程序,我想使用已编译的绑定系统。

我有一个扩展包含属性Windows.UI.Xaml.Controls.Page的{​​{1}}的基础。

这里是ViewModel属性的基类:

ViewModel

这是我的基页:

 public class BaseViewModel : INotifyPropertyChanged
 {

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaiseOnPropertyChanged([CallerMemberName] string propertyName = "")
    {
      OnPropertyChanged(propertyName);
    }

    public void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
    }

  }

我的应用页面扩展了public abstract class BasePage : Page { public BaseViewModel ViewModel { get; set; } } 并包含一个扩展BasePage类的nester(内部)类。这是一个示例代码:

BaseViewModel

现在,我想将public sealed partial class MyPage : BasePage { public sealed class MyViewModel : BaseViewModel { public string Title { get { return "Test"; } } } public MyPage() { InitializeComponent(); ViewModel = MyViewModel(); } } 类的属性Title绑定到我的UI。根据{{​​3}}和this article,类似的内容应该有效:

MyViewModel

不幸的是,我无法编译。由于“+”字符,我在生成的文件<TextBlock Text="{x:Bind ViewModel.(namespace:MyPage+MyViewModel.Title)}" /> 上有几个错误。你知道UWP应用程序是否支持嵌套(内部)类的绑定?也许它仅在WPF应用程序上受支持? :(

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

{x:Bind}中使用“+”字符进行投射时出现问题。在 MyPage.xaml 中使用{x:Bind ViewModel.(local:MyPage+MyViewModel.Title)}时,它会在 MyPage.g.cs 中生成以下代码来更新绑定数据:

private void Update_ViewModel(global::UWP.BaseViewModel obj, int phase)
{
    if (obj != null)
    {
        if ((phase & (NOT_PHASED | (1 << 0))) != 0)
        {
            this.Update_ViewModel__local_MyPage+MyViewModel_Title_(((global::UWP.MyPage.MyViewModel)(obj)).Title, phase);
        }
    }
}
private void Update_ViewModel__local_MyPage+MyViewModel_Title_(global::System.String obj, int phase)
{
    if((phase & ((1 << 0) | NOT_PHASED )) != 0)
    {
        XamlBindingSetters.Set_Windows_UI_Xaml_Controls_TextBlock_Text(this.obj2, obj, null);
    }
}

虽然生成的强制转换是正确的,但方法名称Update_ViewModel__local_MyPage+MyViewModel_Title_无效。因此,现在不支持在{x:Bind}中构建嵌套类。

如果您想使用{x:Bind},可以使用MyViewModel代替BaseViewModel,效果如下。

在代码隐藏中:

public sealed partial class MyPage : BasePage
{
    public MyViewModel myViewModel;

    public sealed class MyViewModel : BaseViewModel
    {
        public string Title
        {
            get
            {
                return "Test";
            }
        }
    }

    public MyPage()
    {
        InitializeComponent();
        myViewModel = new MyViewModel();
    }
}

在XAML中:

<TextBlock Text="{x:Bind myViewModel.Title}" />

此外,如果您要使用BaseViewModel,则可以使用{Binding}代替{x:Bind},因为{Binding}使用通用运行时对象检查。

在代码隐藏中:

public sealed partial class MyPage : BasePage
{
    public sealed class MyViewModel : BaseViewModel
    {
        public string Title
        {
            get
            {
                return "Test";
            }
        }
    }

    public MyPage()
    {
        InitializeComponent();
        ViewModel = new MyViewModel();
        this.DataContext = this;
    }
}

在XAML中:

<TextBlock Text="{Binding ViewModel.Title}" />

答案 1 :(得分:0)

解决方案是使用新属性以避免强制转换和嵌套类访问XAML文件。所以解决方案是使用类似的东西:

public sealed partial class MainPage : BasePage
{

  public sealed class MyViewModel : BaseViewModel
  {
    public string Title
    {
      get
      {
        return "Test";
      }
    }
  }

  public MyViewModel LocalViewModel
  {
    get
    {
      return (MyViewModel) ViewModel;
    }
  }

  public MainPage()
  {
    this.InitializeComponent();
    ViewModel = new MyViewModel();
  }
}

因此,使用x:Bind语法,XAML看起来像:

<TextBlock Text="{x:Bind LocalViewModel.Title}" />