まず、VatCodeViewModelのプロパティVatCodeの編集に凝縮できる背景。
ViewModelに2つの特定のプロパティを持つ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");
}
}
}
}
および実装クラス(StockItemViewModelのItemを持つEditStockItemViewModel)..。
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:''(タイプ'VatCodeViewModel')から'Item'値(タイプ'String')を取得できません。BindingExpression:Path = Item.VatCode; DataItem ='VatCodeViewModel'(HashCode = 27875274); ターゲット要素は'RadComboBox'(Name ='');です。ターゲットプロパティは'NoTarget'(タイプ'Object')ですTargetParameterCountException:'System.Reflection.TargetParameterCountException:パラメーターカウントの不一致。
明らかにエラーは私のバインディング式Item.VatCodeが疑わしいことを示していますが、それを修正する方法がわかりません。