0

首先是一些背景知识,可以浓缩为编辑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 作为源的增值税代码。

该列表已填充并且看起来很好。我知道 ViewModel 绑定正确。

问题是增值税代码没有绑定到 Item.VatCode 属性。因此,当我使用 Save 方法时,Item.VatCode 属性为空(即不工作)。

我收到以下似乎相关的绑定错误:

System.Windows.Data 错误:17:无法从“”(类型“VatCodeViewModel”)获取“项目”值(类型“字符串”)。BindingExpression:Path=Item.VatCode; DataItem='VatCodeViewModel' (HashCode=27875274); 目标元素是 'RadComboBox' (Name=''); 目标属性是“NoTarget”(类型“对象”) TargetParameterCountException:“System.Reflection.TargetParameterCountException:参数计数不匹配。

显然,该错误表明我的绑定表达式 Item.VatCode 是可疑的,但我不确定如何更正它。

4

2 回答 2

1

我认为问题在于您的组合框标记的这一行:

ItemsSource="{Binding VatCodes}" SelectedValuePath="Item.VatCode" 

这表示要从VatCodes(类型VatCodeViewModel)中提取组合框的项目,并为组合框值获取一个名为Item.VatCode的VatCodeViewModel属性。没有看到VatCodeViewModel的定义很难说,但我怀疑该属性不存在。

这就是我认为你的意思。使SelectedValuePath成为VatCodeViewModel的属性(假设是VatCode),然后将选择绑定到Item.VatCode。你可以这样做:

ItemsSource="{Binding VatCodes}" SelectedValuePath="VatCode" SelectedValue="{Binding Item.VatCode}"
于 2012-05-17T16:50:33.210 回答
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>
于 2012-05-18T09:27:09.943 回答