XAML中的Bindingerror和UWP中的MVVM(使用C#)

时间:2018-05-22 10:20:50

标签: c# mvvm uwp

我在使用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的{​​{1}}设置为此ComboBox。 我试图直接绑定到ViewModel,但是当我导航到另一个站点并且我想避免尽可能多地RuleSet时,这个会从RAM中删除,所以我创建了一个实例在第一个站点上的ViewModel,并将其作为参数提供给第二页。到目前为止效果很好,但现在我必须将static绑定到ComboBox以及那些我没有获得正确代码的地方。 也许我从错误的一面接近这个?建议如何从一个站点访问另一个站点的数据,而不是将整个实例从A到B提供给C等等? 这不起作用:
查看:

this._editRulesViewModel.RuleSet.RuleMainSystems

在XAML中:

public sealed partial class EditRules
{
    private EditRulesViewModel _editRulesViewModel;

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

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

我的意思是,是的,数据到达第二页,但<ComboBox x:Name="MainSystemComboBox" DisplayMemberPath="Name" ItemsSource="_editRulesViewModel.RuleSet.RuleMainSystems" /> 是错误的。 哦,我还尝试在XAML页面定义中设置DataContext:

Binding

2 个答案:

答案 0 :(得分:1)

你可以尝试实现INotifyPropertyChanged-Event。

或者将元素添加到列表中,如下所示:

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" />

答案 1 :(得分:1)

首先,{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}" />