绑定 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.");
}
我有一个网格元素,其 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
使用 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.");
}