【问题标题】:WPF Data Binding Errors Getting a System.Windows.Data Error: 40WPF 数据绑定错误获取 System.Windows.Data 错误:40
【发布时间】:2019-02-16 08:22:27
【问题描述】:

我不断收到此错误: System.Windows.Data 错误:40: BindingExpression 路径错误:

System.Windows.Data 错误:40:BindingExpression 路径错误:

  • 在 'object' ''MainWindow' (Name='')' 上找不到'ViewModels' 属性。

  • BindingExpression:Path=ViewModels.EventViewModel.EventName;

  • DataItem='MainWindow' (Name='');

  • 目标元素是'ComboBox' (Name='EventNameComboBox');

  • 目标属性为“SelectedItem”(类型为“Object”)

MainWindow.XAML

    <ComboBox Name="EventNameComboBox"
              DisplayMemberPath="EventName"
              HorizontalContentAlignment="Center"
              ItemsSource="{Binding Path=EventViewModels}"
              materialDesign:HintAssist.Hint="Select an Event"
              SelectionChanged="EventNameComboBox_SelectionChanged"
              Width="400">
        <ComboBox.SelectedItem>
            <Binding Path="ViewModels.EventViewModel.EventName" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <validationRules:EventNameValidationRule ValidatesOnTargetUpdated="True"/>
                </Binding.ValidationRules>
            </Binding>
        </ComboBox.SelectedItem>
        <ComboBox.ItemsPanel>
         <ItemsPanelTemplate>
             <VirtualizingStackPanel/>
         </ItemsPanelTemplate>
        </ComboBox.ItemsPanel>
    </ComboBox>

EventNameValidationRule.cs

public class EventNameValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string eventName = value == null ? "" : value.ToString();

        return string.IsNullOrEmpty(eventName)
            ? new ValidationResult(false, "Please select a Event")
            : ValidationResult.ValidResult;
    }
}

最后,

EventViewModel.cs

public class EventViewModel : INotifyPropertyChanged
{
    private int _eventId;
    private string _eventName;


    public int EventId
    {
        get { return _eventId; }
        set
        {
            _eventId = value;
            OnPropertyChanged("EventId");
        }

    }

    public string EventName
    {
        get { return _eventName; }
        set
        {
            _eventName = value;
            OnPropertyChanged("EventName");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

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

我不确定发生了什么。

更新

MainWindow.xaml.cs

private List<EventViewModel> _eventViewModels;

public List<EventViewModel> EventViewModels
{
    get { return _eventViewModels; }
    set { _eventViewModels = value; OnPropertyChanged("EventViewModels"); }
}

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


public MainWindow()
{
    InitializeComponent();

    EventViewModels = new List<EventViewModel>();
    int year = 2008;
    for (int i = 1; i <= 10; i++)
    {
        EventViewModel viewModel = new EventViewModel();
        viewModel.EventId = i;
        viewModel.EventName = $"{year} Test Event";

        ++year;

        EventViewModels.Add(viewModel);
    }

    DataContext = this;
} 

【问题讨论】:

  • 你能告诉你在哪里设置数据上下文吗?
  • @Lance 好的,我添加了 MainWindow.xaml.cs
  • @Lance 这也很奇怪,因为当我第一次运行项目时它看起来正在工作,但是在它决定它不会做任何事情之后,当我在 ComboBox 中选择不同的项目时它就像验证规则未更新 XAML 以清除旧的验证错误

标签: c# wpf xaml material-design-in-xaml


【解决方案1】:

您的代码中有两点需要注意:

  1. 绑定路径 ViewModels.EventViewModel.EventName 不正确。绑定路径应基于控件的绑定或 DataContext,在您的情况下是 MainWindow.xaml.cs,并且该类没有属性“ViewModels.EventViewModel.EventName”。

  2. 您不能将 EventName 属性绑定到 SelectedItem,因为 SelectedItem 应该绑定到 EventViewModel 类型,因为项目源是 EventViewModel 的列表

你需要做什么:

  1. 创建正确的绑定。为此,您必须在 MainWindow 类中声明一个 EventViewModel 属性,我们称之为 SelectedEvent。将以下内容添加到 MainWindow.xaml.cs

private EventViewModel _SelectedEvent; public EventViewModel SelectedEvent { get { return _SelectedEvent; } set { _SelectedEvent = value; OnPropertyChanged("SelectedEvent"); } }

  1. 您需要更改ComboBox中SelectedItem的绑定路径。将其绑定到新的属性 SelectedEvent。现在,每次您在组合框中选择一个项目时,SelectedEvent 属性都会发生变化。

<ComboBox.SelectedItem> <Binding Path="SelectedEvent" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:EventNameValidationRule ValidatesOnTargetUpdated="True"/> </Binding.ValidationRules> </Binding> </ComboBox.SelectedItem>

  1. 由于绑定已更改,验证规则现在需要在 value 参数中添加 EventViewModel。因此,您需要稍微调整一下 ValidateMethod。

public override ValidationResult Validate(object value, CultureInfo cultureInfo) { if (value == null) return new ValidationResult(false, "Please select a Event"); if (value is EventViewModel eventVm) { string eventName = eventVm.EventName == null ? "" : value.ToString(); return string.IsNullOrEmpty(eventName) ? new ValidationResult(false, "Please select a Event") : ValidationResult.ValidResult; } throw new Exception("Invalid binding!"); }

【讨论】:

  • 哇,哇,哇!多么愚蠢的错误!我正在尝试学习 MVVM。非常感谢您@Lance 的帮助!
  • 不客气!关键是您必须问自己哪个类是您遇到问题的控件的数据上下文/绑定源。
猜你喜欢
  • 1970-01-01
  • 2015-08-11
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 2021-02-13
  • 2018-08-09
  • 2011-04-26
  • 2011-02-06
相关资源
最近更新 更多