Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更改视图模型_C#_Xaml_Mvvm_Uwp_Xbind - Fatal编程技术网

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();
}