Ошибки привязки данных WPF Получение System.Windows.Data Ошибка: 40 - PullRequest
0 голосов
/ 11 сентября 2018

Я получаю эту ошибку: Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression:

Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression:

  • Свойство 'ViewModels' не найдено в 'объекте' '' MainWindow '(Name =' ')'.

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

Я не уверен, что происходит.

UPDATE

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 голосов
/ 11 сентября 2018

В вашем коде есть две вещи, требующие внимания:

  1. Неверный путь привязки ViewModels.EventViewModel.EventName.Путь привязки должен быть основан на привязке или DataContext элемента управления, который в вашем случае является MainWindow.xaml.cs, и этот класс не имеет свойства "ViewModels.EventViewModel.EventName".

  2. Невозможно привязать свойство EventName к SelectedItem, поскольку SelectedItem должен быть привязан к типу EventViewModel, поскольку источником элемента является список EventViewModel

Что нужно сделать:

  1. Создать правильную привязку.Для этого необходимо объявить свойство EventViewModel в классе MainWindow, назовем его SelectedEvent.Добавьте следующее к вам MainWindow.xaml.cs

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

Вам необходимо изменить путь привязки SelectedItem в ComboBox.Свяжите его с новым свойством SelectedEvent.Теперь каждый раз, когда вы выбираете элемент в поле со списком, свойство SelectedEvent будет меняться.

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

Поскольку привязка была изменена, теперь правило проверки будет ожидать EventViewModel в параметре value.Поэтому вам нужно немного настроить метод 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!"); }

...