【发布时间】:2012-05-17 16:22:54
【问题描述】:
首先是一些背景知识,可以浓缩为编辑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的Item)...
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 绑定正确。
问题是增值税代码没有绑定到 Item.VatCode 属性。因此,当我使用 Save 方法时,Item.VatCode 属性为空(即不工作)。
我收到以下似乎相关的绑定错误:
System.Windows.Data 错误:17:无法获取“项目”值(类型 '字符串')来自''(类型'VatCodeViewModel')。 BindingExpression:Path=Item.VatCode; DataItem='VatCodeViewModel' (哈希码=27875274);目标元素是 'RadComboBox' (Name='');目标 属性是“NoTarget”(类型“对象”) TargetParameterCountException:'System.Reflection.TargetParameterCountException: 参数计数不匹配。
显然错误表明我的绑定表达式 Item.VatCode 是可疑的,但我不确定如何更正它。
【问题讨论】: