我目前正在研究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应用程序上受支持? :(
感谢您的帮助!
答案 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}" />