绑定 x:Load,更新绑定值不加载控件 (UWP)

Binding x:Load, updating bound value doesn't load the control (UWP)

我有一个网格元素,其 x:Load 属性绑定到页面中的一个变量:

Page.xaml

<Page>
...
    <Grid x:Name="grd" x:Load="{x:Bind LoadGrid, Mode=OneWay}">

Page.xaml.cs

public sealed partial class Page : Page
...
bool LoadGrid;

OnNavigatedTo事件处理程序接收到传递的参数后,我相应地设置了LoadGrid的值:

request = (Request) e.Parameter;

if (request == null)
    LoadGrid = false;
else {
    LoadGrid = true;
    InitializeComponent(); // Tried adding this to refresh the controls.
    grd.Loaded += grd_Loaded;
}

执行行grd.Loaded += grd_Loaded;时,抛出ArgumentException:

An exception of type 'System.ArgumentException' occurred ...
Delegate to an instance method cannot have null 'this'.

我检查 grd 的值是 null 即使 x:Load 属性 是真的并且绑定模式是单向的(控件 "checks" 更新绑定值)。

编辑

尝试 1

正在调用 this.InitializeComponent() 重新初始化控件。

ATTEMPT 2 @touseefbsb:

使用 MVVM 方法创建用于更新 属性 值的事件。

尝试 3

设置负载值后试过.FindName("grd"),没用。

OneWay 绑定还需要 属性 使用 INotifyPropertyChanged 接口。

首先,您的 LoadGrid 应该是一个 属性 而不是像以下

这样的字段
public bool LoadGrid {get; set;}

之后你需要实现 INotifyPropertyChanged ,它最好与 ViewModel ( MVVM pattren ) 一起使用

制作一个 ViewModel class 实现。

public class PageViewModel : INotifyPropertyChanged
{
    private bool loadGrid;

    public event PropertyChangedEventHandler PropertyChanged = delegate { };


    public bool LoadGrid
    {
        get { return this.loadGrid; }
        set
        {
            this.loadGrid = value;
            this.OnPropertyChanged();
        }
    }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        // Raise the PropertyChanged event, passing the name of the property whose value has changed.
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

之后,在您的页面中创建一个类型为 PageViewModel 的 属性,例如:

public PageViewModel vm {get;设置;} = 新的 PageViewModel();

然后在您的 OnNavigatedTo() 方法中,您可以根据需要设置 属性。而且你不需要再次调用 InitializeComponent 来刷新任何东西。

if (request == null)
    vm.LoadGrid = false;
else {
    vm.LoadGrid = true;
    grd.Loaded += grd_Loaded;
}

您需要做的最后一个更改是 xaml 中的一点更改,只需绑定到 vm.LoadGrid 而不是 LoadGrid,如下所示:

<Grid x:Name="grd" x:Load="{x:Bind vm.LoadGrid, Mode=OneWay}">

more details on data binding in depth : https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth

Unlike in prior XAML platforms, the OnNavigated method is called before the visual tree is loaded.

因此,您可以在页面的加载事件处理程序中注册网格的加载事件,如下所示:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    var request = e.Parameter;

    if (request == null)
        LoadGrid = false;
    else
    {
        LoadGrid = true;
        InitializeComponent();
        this.Loaded += BlankPage1_Loaded;
    }
 }

private void BlankPage1_Loaded(object sender, RoutedEventArgs e)
{
    grd.Loaded += Grd_Loaded;
}

private void Grd_Loaded(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("Grd loaded.");
}