Bindingerror в XAML и MVVM в UWP (с C #) - PullRequest
0 голосов
/ 22 мая 2018

У меня проблема с правильной реализацией привязки данных с MVVM и ComboBox.У меня есть простая модель:

public class RuleSet
{
    public List<RuleMainSystem> RuleMainSystems { get; set; }

    public RuleSet()
    {
        RuleMainSystems = new List<RuleMainSystem>();
    }
}

И в ней это выглядит так:

public class RuleMainSystem
{
    public string Name { get; set; }
    public List<RuleSubSystem> RuleSubSystems { get; set; }

    public RuleMainSystem(string name)
    {
        Name = name;
        RuleSubSystems = new List<RuleSubSystem>();
    }
}

Теперь я хочу простую привязку со страницы, частью которой является ComboBox, аItemSource из этого ComboBox будет установлено на этот RuleSet.Я пытался привязать напрямую к ViewModel, но этот удаляется из оперативной памяти, как только я перехожу на другой сайт, и я хочу избежать максимально возможного static, поэтому я создал экземпляр этой ViewModel наПервый сайт и дать его на второй странице в качестве параметра.Пока это хорошо работает, но теперь мне придется привязать ComboBox к this._editRulesViewModel.RuleSet.RuleMainSystems, и именно здесь я не могу получить правильный код.Может быть, я подхожу к этому не с той стороны?Предложение, как я мог бы получить доступ к данным с одного сайта на другой, не передавая целые экземпляры от А до Б к С и т. Д.
Это не работает:
Просмотр:

public sealed partial class EditRules
{
    private EditRulesViewModel _editRulesViewModel;

    public EditRules()
    {
        DataContext = this;
        InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        _editRulesViewModel = (EditRulesViewModel)e.Parameter;
    }
}

И в XAML:

<ComboBox x:Name="MainSystemComboBox" DisplayMemberPath="Name" ItemsSource="_editRulesViewModel.RuleSet.RuleMainSystems" />

Я имею в виду, да, данные поступают на вторую страницу, но Binding неверно.Да, и я также попытался установить DataContext в определении страницы XAML:

DataContext="{Binding RelativeSource={RelativeSource Self}}"

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Во-первых, {Binding} не работает с полями private.Вместо этого вы должны выставить их как public свойства.Более новое расширение {x:Bind} работает с полями public, но не с private.

Далее - вам нужно использовать синтаксис {Binding} во всех местах, где выполняется привязка данных - поэтому для ItemsSource также недостаточно написать имя переменной напрямую.

Наконец, чтобы все это заработало, вам также нужно будет внедрить INotifyPropertyChanged на странице, потому что во время OnNavigatedTo привязка данных уже запущена, так что в противном случае она не будет привязывать вновь назначенное значение.

public sealed partial class EditRules : INotifyPropertyChanged
{ 
    public EditRulesViewModel EditRulesViewModel {get; private set;}

    public EditRules()
    {
        DataContext = this;
        InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        EditRulesViewModel = (EditRulesViewModel)e.Parameter;
        OnPropertyChanged(nameof(this.EditRulesViewModel));
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Сейчас в XAML выполните:

<ComboBox x:Name="MainSystemComboBox" DisplayMemberPath="Name"
    ItemsSource="{Binding EditRulesViewModel.RuleSet.RuleMainSystems}" />
0 голосов
/ 22 мая 2018

вы можете попытаться реализовать событие INotifyPropertyChanged.

Или добавить элементы в список следующим образом:

public sealed partial class EditRules
{
private List<object> _editRulesViewModel = new List<object>();

public EditRules()
{
    DataContext = this;
    InitializeComponent();
}

//Add nullchecking, etc.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    _editRulesViewModel.Clear();
    foreach (item in ((EditRulesViewModel)e.Parameter)RuleSet.RuleMainSystems)
    {        
        _editRulesViewModel.Add(item);
    }
}
}

<ComboBox x:Name="MainSystemComboBox" DisplayMemberPath="Name" ItemsSource="_editRulesViewModel" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...