【问题标题】:How can I solve this XAML Binding error?如何解决此 XAML 绑定错误?
【发布时间】: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 是可疑的,但我不确定如何更正它。

【问题讨论】:

    标签: wpf xaml mvvm


    【解决方案1】:

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

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

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

    这就是我认为你要做的事情。使 SelectedValuePath 成为 VatCodeViewModel 的一个属性(比如说 VatCode),然后将选择绑定到 Item.VatCode。你可以这样做:

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

    【讨论】:

    • 谢谢,抱歉,这不起作用。我正在使用您在 的拆分代码中建议的 SelectedValue 表达式。将 SelectedValuePath 更改为 VatCode 也不起作用。希望我能投票支持你。
    【解决方案2】:

    找到了,我被文档中提供的示例误导了。我不应该使用路径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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2012-02-14
      • 2015-04-12
      • 2016-06-21
      相关资源
      最近更新 更多