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 路径错误:
'ViewModels' 属性 未在 'object' 上找到 ''MainWindow' (Name='')'.
绑定表达式:路径=ViewModels.EventViewModel.EventName;
DataItem='MainWindow' (名称='');
目标元素是'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;
}
您的代码中有两点需要注意:
绑定路径ViewModels.EventViewModel.EventName不正确。绑定路径应基于控件的绑定或 DataContext,在您的情况下是 MainWindow.xaml.cs 而 class 没有 属性 "ViewModels.EventViewModel.EventName ".
您不能将 EventName 属性 绑定到您的 SelectedItem,因为 SelectedItem 应该绑定到一种类型的 EventViewModel,因为项目源是 EventViewModel
的列表
您需要做的事情:
- 创建正确的绑定。为此,您必须在 MainWindow class 中声明一个 EventViewModel 属性,我们称它为 SelectedEvent。添加以下内容给你MainWindow.xaml.cs
public EventViewModel SelectedEvent
{
get { return _SelectedEvent; }
set { _SelectedEvent = value; OnPropertyChanged("SelectedEvent"); }
}
- 您需要更改ComboBox中SelectedItem的绑定路径。将其绑定到新的 属性 SelectedEvent。现在,每次 select 组合框中的一个项目,SelectedEvent 属性 都会改变。
<ComboBox.SelectedItem>
<Binding Path="SelectedEvent" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:EventNameValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
- 由于绑定已更改,验证规则现在需要值参数中的 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!");
}
我不断收到此错误: System.Windows.Data 错误:40: BindingExpression 路径错误:
System.Windows.Data 错误:40:BindingExpression 路径错误:
'ViewModels' 属性 未在 'object' 上找到 ''MainWindow' (Name='')'.
绑定表达式:路径=ViewModels.EventViewModel.EventName;
DataItem='MainWindow' (名称='');
目标元素是'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;
}
您的代码中有两点需要注意:
绑定路径ViewModels.EventViewModel.EventName不正确。绑定路径应基于控件的绑定或 DataContext,在您的情况下是 MainWindow.xaml.cs 而 class 没有 属性 "ViewModels.EventViewModel.EventName ".
您不能将 EventName 属性 绑定到您的 SelectedItem,因为 SelectedItem 应该绑定到一种类型的 EventViewModel,因为项目源是 EventViewModel
的列表
您需要做的事情:
- 创建正确的绑定。为此,您必须在 MainWindow class 中声明一个 EventViewModel 属性,我们称它为 SelectedEvent。添加以下内容给你MainWindow.xaml.cs
public EventViewModel SelectedEvent
{
get { return _SelectedEvent; }
set { _SelectedEvent = value; OnPropertyChanged("SelectedEvent"); }
}
- 您需要更改ComboBox中SelectedItem的绑定路径。将其绑定到新的 属性 SelectedEvent。现在,每次 select 组合框中的一个项目,SelectedEvent 属性 都会改变。
<ComboBox.SelectedItem>
<Binding Path="SelectedEvent" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:EventNameValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
- 由于绑定已更改,验证规则现在需要值参数中的 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!");
}