WPF数据绑定错误获取System.Windows.Data错误:40

时间:2018-09-11 18:56:19

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

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

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

  • 在“对象”“ MainWindow”(名称=“)”上找不到“ ViewModels”属性。

  • BindingExpression:Path = ViewModels.EventViewModel.EventName;

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

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

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

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;
} 

1 个答案:

答案 0 :(得分: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的绑定路径。将其绑定到新的Property 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!"); }