首先是一些背景,可以压缩成编辑VatCodeViewModel的属性VatCode。
我在ViewModel中有一个具有两个特定属性的StockItem:
public class StockItemViewModel : ViewModelBase
{
private VatCodeViewModel _vatCode;
public VatCodeViewModel VatCode
{
get { return _vatCode; }
set
{
if (_vatCode != value)
{
_vatCode = value;
RaisePropertyChanged("VatCode");
}
}
}
}
VatCode属性接受VatCodeViewModel类型。
为了管理编辑体验,我有一个名为EditStockItemViewModel的ViewModel。这有元数据,如IsDirty,IsNew等,但是Item属性设置为正在编辑的项目 - 在这种情况下是StockItemViewModel的实例。 Item属性位于基类中(TViewModel == StockItemViewModel)......
public class UnMappedEditableViewModelBase<TViewModel> : ViewModelBase
{
private TViewModel _item;
public TViewModel Item
{
get { return _item; }
set
{
if (_item != value)
{
_item = value;
RaisePropertyChanged("Item");
}
}
}
}
和实现类(EditStockItemViewModel,它具有StockItemViewModel项)...
public class EditStockItemViewModel : UnMappedEditableViewModelBase<StockItemViewModel>
{
private ObservableCollection<VatCodeViewModel> _vatCodes=new ObservableCollection<VatCodeViewModel>();
public ObservableCollection<VatCodeViewModel> VatCodes
{
get { return _vatCodes; }
set
{
if (_vatCodes != value)
{
_vatCodes = value;
RaisePropertyChanged("VatCodes");
}
}
}
public EditStockItemViewModel()
:base()
{
if (IsInDesignMode)
{
}
else
{
RefreshVatCodesList(null); // refreshes VatCodes property
Save = new RelayCommand(() =>
{
// save functionality snipped
}, () =>
{
bool canExecute = Item.VatCode!=null; // this is ALWAYS null - binding failing
return canExecute;
});
}
}
}
因此,ViewModel.Item属性始终是正在编辑的项目。
我的观点片段......
<TextBlock Text="VAT Code:" Grid.Column="1" Grid.Row="3" Style="{StaticResource ComboHeaderTextBlock}" />
<telerik:RadComboBox Grid.Column="2" Grid.Row="3" Style="{StaticResource RadComboBox}" Width="300" HorizontalAlignment="Left"
ItemsSource="{Binding VatCodes}" SelectedValuePath="Item.VatCode"
ClearSelectionButtonVisibility="Collapsed"
CanAutocompleteSelectItems="True"
CanKeyboardNavigationSelectItems="True"
IsEditable="False"
OpenDropDownOnFocus="False"
IsFilteringEnabled="False"
EmptyText="Select ...">
<telerik:RadComboBox.SelectedValue>
<Binding Path="Item.VatCode" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" RelativeSource="{RelativeSource FindAncestor,AncestorType={x:Type UserControl}}" >
<Binding.ValidationRules>
<DataErrorValidationRule />
</Binding.ValidationRules>
</Binding>
</telerik:RadComboBox.SelectedValue>
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Key}" Style="{StaticResource TextBlock}" />
<TextBlock Text="{Binding Name}" Style="{StaticResource DimTextBlock}" />
<TextBlock Text="{Binding ActiveRate.Rate}" Margin="5 5 0 5" />
<TextBlock Text="%" Margin="0 5 5 5" />
</StackPanel>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
所以在这一切结束时,我有:
绑定到[ViewModel] .Item.VatCode并使用[ViewModel] .VatCodes作为源的VatCode。
列表已填充并显示正常。我知道ViewModel绑定正确。
问题是VatCode没有绑定到Item.VatCode属性。所以当我进入Save方法时,Item.VatCode属性为null(即不工作)。
我收到以下绑定错误,似乎是相关的:
System.Windows.Data错误:17:无法获取'Item'值(类型 来自''的'String')(类型'VatCodeViewModel')。 BindingExpression:路径= Item.VatCode;的DataItem = 'VatCodeViewModel' (的HashCode = 27875274); target元素是'RadComboBox'(Name ='');目标 属性是'NoTarget'(类型'对象') TargetParameterCountException:“System.Reflection.TargetParameterCountException: 参数计数不匹配。
显然错误表明我的绑定表达式Item.VatCode是可疑的,但我不确定如何纠正它。
答案 0 :(得分:1)
我认为问题出现在你的组合框标记的这一行:
ItemsSource="{Binding VatCodes}" SelectedValuePath="Item.VatCode"
这表示从 VatCodes (类型 VatCodeViewModel )中提取组合框的项目,对于组合框值,请使用 VatCodeViewModel的属性名为 Item.VatCode 。如果没有看到 VatCodeViewModel 的定义,很难说,但我怀疑该属性不存在。
这就是我认为你的意思。将 SelectedValuePath 设为 VatCodeViewModel 的属性(假设为 VatCode ),然后将选择绑定到 Item.VatCode 。你可以这样做:
ItemsSource="{Binding VatCodes}" SelectedValuePath="VatCode" SelectedValue="{Binding Item.VatCode}"
答案 1 :(得分:0)
发现它,我被文档中提供的示例误导了。我不应该使用路径SelectedValuePath。所以我的新代码是:
<TextBlock Text="VAT Code:" Grid.Column="1" Grid.Row="3" Style="{StaticResource ComboHeaderTextBlock}" />
<telerik:RadComboBox Grid.Column="2" Grid.Row="3" Style="{StaticResource RadComboBox}" Width="300" HorizontalAlignment="Left"
ItemsSource="{Binding VatCodes}"
ClearSelectionButtonVisibility="Collapsed"
CanAutocompleteSelectItems="True"
CanKeyboardNavigationSelectItems="True"
IsEditable="False"
OpenDropDownOnFocus="False"
IsFilteringEnabled="False"
EmptyText="Select ...">
<telerik:RadComboBox.SelectedValue>
<Binding Path="Item.VatCode" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<DataErrorValidationRule />
</Binding.ValidationRules>
</Binding>
</telerik:RadComboBox.SelectedValue>
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Key}" Style="{StaticResource TextBlock}" />
<TextBlock Text="{Binding Name}" Style="{StaticResource DimTextBlock}" />
<TextBlock Text="{Binding ActiveRate.Rate}" Margin="5 5 0 5" />
<TextBlock Text="%" Margin="0 5 5 5" />
</StackPanel>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>