【问题标题】:Combobox displays namespace.ViewModel组合框显示 namespace.ViewModel
【发布时间】:2012-09-07 08:50:21
【问题描述】:

我有一个绑定到ObservableCollection<CustomerViewModel>的组合框

<ComboBox ItemsSource="{Binding AllCustomers}" IsEditable="True"/>

如果我使用 DisplayMemberPath 属性,下拉列表和选定项会正确显示

<ComboBox ItemsSource="{Binding AllCustomers}" DisplayMemberPath="CustomerName" IsEditable="True"/>

但是如果分配了一个DataTemplate,被选中的item就不能正常显示

<ComboBox ItemsSource="{Binding AllCustomers}" SelectedValue="CustomerName" IsEditable="True">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding CustomerName}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ComboBox>

编辑: 我找到了问题,但没有找到解决方案,问题是如果 ComboBox 具有 IsEditable="True" 它会产生问题。


代码摘要:

public class AllCustomersViewModel
{
   public ObservableCollection<CustomerViewModel> AllCustomers {get; set;}
}

public class CustomerViewModel
{
   public string CustomerName;
   public short CustomerID;
}

要设置(或如何)正确显示所选值/项目的属性。

非常感谢您。



实际代码

public class AccountTransactionsViewModel
{
    DataRepository _repository;

    public AccountTransactionsViewModel()
    {
        _repository = new DataRepository();
        CreateAccountsViewModel();
    }

    public ObservableCollection<AccountViewModel> AllAccounts { get; set; }

    void CreateAccountsViewModel()
    {
        List<AccountViewModel> allAccounts = _repository.GetAccounts()
                                                        .Select(a => new AccountViewModel(a, _repository))
                                                        .ToList();

        AllAccounts =  new ObservableCollection<AccountViewModel>(allAccounts);            
    }
}



  public class AccountViewModel
  {
       Account _account;
       DataRepository _repository;

       public AccountViewModel(Account account, DataRepository repository)
       {
            _account = account;
            _repository = repository;
       }

       public short AccountID { get { return _account.AccountID; } set { } }
       public string AccountName { get { return _account.AccountName; } set { } }        
  }

XAML:

<ComboBox Name="customerCombobox" ItemsSource="{Binding AllAccounts}" IsEditable="True">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding AccountName}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>                     
                    </ComboBox>

编辑:

我找到了问题,但没有找到解决方案,问题是如果 ComboBox 具有 IsEditable="True" 则会产生问题。

【问题讨论】:

  • 您的示例中有问题:代码中有 AccountName,XAML 中有 CustomerName。你能发布你的实际代码吗?因为设置ItemTemplate 也应该影响所选项目,并且您的代码应该可以工作。
  • @nemesv:哦,是的,抱歉……我更正了。这是因为我在这里手动输入了数据类。
  • 检查 VS 输出中的绑定错误,他们会提示失败的原因。我也不确定这样设置 SelectedValue 是否有效。
  • @stijn 输出中绝对没有 BindingExpression 错误。 :(

标签: c# wpf xaml data-binding


【解决方案1】:

我遇到了同样的问题,因为我想在组合框项目中显示自定义文本。 当你有一个ItemTemplate 时,你不能设置ComboBox 的DisplayMemberPath 在你没有实现toString() 函数时显示类名。

您只需使用TextSearch.TextPath 即可解决您的问题。

<ComboBox IsEditable="True" TextSearch.TextPath="MySelectedTextField">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock ToolTip="{Binding MyTooltipField}">
                <Run Text="{Binding MyCustomField1}" />
                <Run Text=" - "/>
                <Run Text="{Binding MyCustomField2}" />
            </TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

【讨论】:

    【解决方案2】:

    如果要显示某些属性的选定值,您应该使用SelectedValuePathSelectedValue 将保存您要显示的 SelectedItems 属性的值。

    如果不设置 SelectedValuePath,框架会尝试取回整个 SelectedItem - 在本例中为 AccountViewModel 实例 - 转换为字符串

    <ComboBox Name="customerCombobox" ItemsSource="{Binding AllAccounts}" SelectedValuePath="AccountName">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding AccountName}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>                     
                    </ComboBox>
    

    【讨论】:

      【解决方案3】:

      当没有可用的模板时,会显示对象类型的全名。此外,完整的类型名称是 ToString() 方法调用的结果。所以要么重写ToString() 方法,要么调查更多关于数据模板的信息。

      【讨论】:

        【解决方案4】:

        试试

        <ComboBox ItemsSource="{Binding AllCustomers}" SelectedValue="CustomerName">
                <ItemsControl.ItemTemplate>
                     <DataTemplate>
                         <TextBlock Text="{Binding Item.CustomerName}"/>
                     </DataTemplate>
                </ItemsControl.ItemTemplate>
        </ComboBox>
        

        【讨论】:

        • 没有项目显示在下拉列表中(如预期的那样)。实际上问题不在于数据模板,而是 SelectedItemTemplate 表现得很奇怪
        猜你喜欢
        • 2015-11-22
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        • 1970-01-01
        • 2013-02-23
        • 2011-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多