WPF Data Binding Errors Getting a System.Windows.Data Error: 40

WPF Data Binding Errors Getting a System.Windows.Data Error: 40

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

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

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. 绑定路径ViewModels.EventViewModel.EventName不正确。绑定路径应基于控件的绑定或 DataContext,在您的情况下是 MainWindow.xaml.cs 而 class 没有 属性 "ViewModels.EventViewModel.EventName ".

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

    的列表

您需要做的事情:

  1. 创建正确的绑定。为此,您必须在 MainWindow class 中声明一个 EventViewModel 属性,我们称它为 SelectedEvent。添加以下内容给你MainWindow.xaml.cs
    public EventViewModel SelectedEvent
    {
        get { return _SelectedEvent; }
        set { _SelectedEvent = value; OnPropertyChanged("SelectedEvent"); }
    }
  1. 您需要更改ComboBox中SelectedItem的绑定路径。将其绑定到新的 属性 SelectedEvent。现在,每次 select 组合框中的一个项目,SelectedEvent 属性 都会改变。
<ComboBox.SelectedItem>
    <Binding Path="SelectedEvent" UpdateSourceTrigger="PropertyChanged">
        <Binding.ValidationRules>
        <local:EventNameValidationRule ValidatesOnTargetUpdated="True"/>
        </Binding.ValidationRules>
    </Binding>
</ComboBox.SelectedItem>
  1. 由于绑定已更改,验证规则现在需要值参数中的 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!"); 
}