C# 更改视图模型
我有一个简化的应用程序来显示我的问题 当我单击按钮时,它会更改C# 更改视图模型,c#,xaml,mvvm,uwp,xbind,C#,Xaml,Mvvm,Uwp,Xbind,我有一个简化的应用程序来显示我的问题 当我单击按钮时,它会更改ViewModel和TextBlock的Text属性。Text会更新 MainPage.xaml <StackPanel> <Button Click="ButtonBase_OnClick">Button to change text</Button> <TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}"></Te
ViewModel
和TextBlock的Text
属性。Text
会更新
MainPage.xaml
<StackPanel>
<Button Click="ButtonBase_OnClick">Button to change text</Button>
<TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}"></TextBlock>
</StackPanel>
ViewModel类有一个字符串属性(文本)并实现了INotifyPropertyChange接口
当未在ctor中设置
ViewModel
时(即ViewModel为null并在运行时更改),问题开始出现:
Complited绑定不起作用(文本未更改),我不明白为什么会如此。。。我需要将viewModel从null更改为null(vm为null,因为它正在实际应用程序中等待一些数据)您是否像这样在页面上实现了
INotifyPropertyChanged
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
private ViewModel viewModel;
public ViewModel ViewModel
{
get { return viewModel; }
set
{
viewModel = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ViewModel)));
}
}
public MainPage()
{
ViewModel = new ViewModel { };
this.InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ViewModel = new ViewModel { };//this line has been added
ViewModel.Text = "x:Bind does not work";
}
public event PropertyChangedEventHandler PropertyChanged;
}
这对我很有用。{x:Bind}绑定(通常称为编译绑定)使用生成的代码来实现其好处。在XAML加载时,{x:Bind}被转换成您可以认为是绑定对象的对象,并且该对象从数据源上的属性获取一个值。这些生成的代码可以在您的
obj
文件夹中找到,名称如下(对于C#).g.cs
对于您的代码,生成的代码如下所示:
// Update methods for each path node used in binding steps.
private void Update_(global::UWP.BlankPage3 obj, int phase)
{
if (obj != null)
{
if ((phase & (NOT_PHASED | DATA_CHANGED | (1 << 0))) != 0)
{
this.Update_ViewModel(obj.ViewModel, phase);
}
}
}
private void Update_ViewModel(global::UWP.ViewModel obj, int phase)
{
this.bindingsTracking.UpdateChildListeners_ViewModel(obj);
if (obj != null)
{
if ((phase & (NOT_PHASED | DATA_CHANGED | (1 << 0))) != 0)
{
this.Update_ViewModel_Text(obj.Text, phase);
}
}
}
...
private global::UWP.ViewModel cache_ViewModel = null;
public void UpdateChildListeners_ViewModel(global::UWP.ViewModel obj)
{
if (obj != cache_ViewModel)
{
if (cache_ViewModel != null)
{
((global::System.ComponentModel.INotifyPropertyChanged)cache_ViewModel).PropertyChanged -= PropertyChanged_ViewModel;
cache_ViewModel = null;
}
if (obj != null)
{
cache_ViewModel = obj;
((global::System.ComponentModel.INotifyPropertyChanged)obj).PropertyChanged += PropertyChanged_ViewModel;
}
}
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ViewModel = new ViewModel();
ViewModel.Text = "x:Bind does not work";
this.Bindings.Update();
}
然后在日期准备就绪时更新这些属性。这样,您就不能在页面上实现INotifyPropertyChanged
接口
除此之外,还有另一种更便宜的方法,您可以调用this.Bindings.Update()代码>方法,用于在初始化ViewModel
后强制更新绑定,如下所示:
// Update methods for each path node used in binding steps.
private void Update_(global::UWP.BlankPage3 obj, int phase)
{
if (obj != null)
{
if ((phase & (NOT_PHASED | DATA_CHANGED | (1 << 0))) != 0)
{
this.Update_ViewModel(obj.ViewModel, phase);
}
}
}
private void Update_ViewModel(global::UWP.ViewModel obj, int phase)
{
this.bindingsTracking.UpdateChildListeners_ViewModel(obj);
if (obj != null)
{
if ((phase & (NOT_PHASED | DATA_CHANGED | (1 << 0))) != 0)
{
this.Update_ViewModel_Text(obj.Text, phase);
}
}
}
...
private global::UWP.ViewModel cache_ViewModel = null;
public void UpdateChildListeners_ViewModel(global::UWP.ViewModel obj)
{
if (obj != cache_ViewModel)
{
if (cache_ViewModel != null)
{
((global::System.ComponentModel.INotifyPropertyChanged)cache_ViewModel).PropertyChanged -= PropertyChanged_ViewModel;
cache_ViewModel = null;
}
if (obj != null)
{
cache_ViewModel = obj;
((global::System.ComponentModel.INotifyPropertyChanged)obj).PropertyChanged += PropertyChanged_ViewModel;
}
}
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ViewModel = new ViewModel();
ViewModel.Text = "x:Bind does not work";
this.Bindings.Update();
}
当然,因为没有关于ViewModel已更改的通知,所以您是说ViewModel属性?如何通知更改-我不想在主页中实现INotifyPropertychange,如果没有魔法,您必须通知页面ViewModel的内容已更改。不管你怎么做,但你必须这么做——你应该使用DataContext属性——已经有一个内置的事件DataContextChanged,绑定系统知道这一点,如果没有INotifyPropertyChange实现,如果你想成功绑定该项,你将不得不做很多事情,而不仅仅是在poco中设置一个属性。如果您不熟悉xaml和绑定,我将研究MVVM的工作方式,您将解决这个问题。我知道这很旧,但非常感谢你。我不知道这个。Bindings.Update()。
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ViewModel = new ViewModel();
ViewModel.Text = "x:Bind does not work";
this.Bindings.Update();
}