Привязка x: загрузка, обновление связанного значения не загружает элемент управления (UWP) - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть элемент сетки с атрибутом 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 имеет значение true, а режим привязки - OneWay (элемент управления «проверяет» наличие обновлений в связанном значении).

Редактирование

ATTEMPT 1

Вызов this.InitializeComponent() для повторного запуска элементов управления.

ATTEMPT 2 предложил @touseefbsb:

Используйте подход MVVM для создания события для обновления значения свойства.

ATTEMPT 3

Попытка .FindName("grd") после установки значения нагрузки не работает.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

В отличие от предыдущих платформ XAML, метод OnNavigated вызывается перед загрузкой визуального дерева.

Таким образом, вы можете зарегистрировать загруженное событие таблицы в обработчике загруженных событий страницы, как показано ниже:

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.");
}
0 голосов
/ 23 сентября 2018

привязка OneWay также требовала, чтобы свойство использовало интерфейс INotifyPropertyChanged .

Прежде всего, LoadGrid должно быть свойством, а непросто поле, подобное следующему

public bool LoadGrid {get; set;}

, после этого вам нужно реализовать INotifyPropertyChanged, который лучше всего использовать с ViewModel (MVVM pattren)

, чтобы создать ViewModel класс с реализацией.

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;set;} = new 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}">

подробнее о привязке данных в глубину: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth

...