gpt4 book ai didi

c# - 更改 View 模型

转载 作者:行者123 更新时间:2023-11-30 23:23:40 25 4
gpt4 key购买 nike

我有简化的应用程序来显示我的问题

当我单击按钮时,它会更改 ViewModelText 属性,并且更新 TextBlock.Text

MainPage.xaml

<StackPanel>
<Button Click="ButtonBase_OnClick">Button to change text</Button>
<TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}"></TextBlock>
</StackPanel>

MainPage.xaml.cs

 public MainPage()
{
ViewModel = new ViewModel();
this.InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ViewModel.Text = "x:Bind works";
}

ViewModel 类具有一个字符串属性(文本)并实现了 INotifyPropertyChange 接口(interface)。


ViewModel 未在 ctor 中设置时(即 viewModel 为 null 并在运行时更改),问题开始:

   public MainPage()
{
//ViewModel = new ViewModel();//this line has been removed
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";
}

Complited binding is not working(文本未更改)我无法弄清楚为什么会这样......我需要将 viewModel 从 null 更改(vm 为 null 因为它正在等待真实应用中的一些数据)

最佳答案

{x:Bind} 绑定(bind)(通常称为编译绑定(bind))使用生成的代码来实现其优势。在 XAML 加载时,{x:Bind} 被转换为您可以认为的绑定(bind)对象,并且该对象从数据源的属性中获取值。这些生成的代码可以在您的 obj 中找到 文件夹,名称类似于 (for C#) <view name>.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;
}
}
}

这里我只是复制一些与您的问题相关的方法。从这些方法中,你可以发现在更新之前 TextBlockPropertyChanged听众,它将检查 ViewModelnull .如果是null ,什么也不会做。所以要使 {x:Bind} 工作,我们必须初始化 ViewModel在页面加载之前。这就是为什么 {x:Bind} 在初始化 ViewModel 时不起作用的原因在 Button.Click事件。

要解决此问题,您可以实现 INotifyPropertyChanged ViewModel 的接口(interface)就像 Filip 说的那样,生成的代码可以在 ViewModel 时得到通知。更改(从 nullnew ViewModel() )并更新您的 UI。

但我认为你可以初始化 ViewModel在构造函数中。当你初始化 ViewModel , 您可以将等待的属性设置为 null第一个喜欢:

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

然后在约会准备就绪时更新这些属性。这样,你可以不执行 INotifyPropertyChanged页面上的界面。

除了这些,还有一个更便宜的方式,可以调用this.Bindings.Update();初始化后强制更新绑定(bind)的方法 ViewModel像下面这样:

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ViewModel = new ViewModel();
ViewModel.Text = "x:Bind does not work";
this.Bindings.Update();
}

关于c# - 更改 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38255505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com