wpf中如何实现Combobox作为ListView某列显示

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf中如何实现Combobox作为ListView某列显示相关的知识,希望对你有一定的参考价值。

在WPF中,如何实现Combobox 作为 ListView 某列显示。要求进行数据库绑定,如与DataTable 中列定义绑定,在没有采用 ComboBox时是这样实现的:
(XMAL)
<ListView Name="listView1" >
<ListView.View>
<GridView>
<GridViewColumn Header="列名" DisplayMemberBinding="Binding ColumnName" />
<GridViewColumn Header="数据类型" DisplayMemberBinding="Binding DataType.Name" />
<GridViewColumn Header="数据长度" DisplayMemberBinding="Binding MaxLength" />
<GridViewColumn Header="允许 null" DisplayMemberBinding="Binding AllowDBNull" >
</GridView>
</ListView.View>
</ListView>

(CODE)
DataTable table=…….; //取得数据表
listView1.ItemsSource = table.Columns;

运行通过,现在要求“数据类型”采用 ComboBox 显示,“数据类型”类型可能有 String,Boolean,Byte[]等多项(例仅为说明问题采用以上3项即可)。修改后的XMAL如下:
<ListView Name="listView1" >
<ListView.View>
<GridView>
<GridViewColumn Header="列名" DisplayMemberBinding="Binding ColumnName" />
<GridViewColumn Header="数据类型" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="Binding Path=DataType.Name,Mode=OneWay" >
<ComboBoxItem Content="String" />
<ComboBoxItem Content="Boolean" />
<ComboBoxItem Content="Byte[]" />
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn> <GridViewColumn Header="数据长度" DisplayMemberBinding="Binding MaxLength" />
<GridViewColumn Header="允许 null" DisplayMemberBinding="Binding AllowDBNull" >
</GridView>
</ListView.View>
</ListView>
遗憾的是,实际运行时只显示了组合框而并不显示选中类型。请问怎样表示才行?谢谢!

参考技术A DataType.Name 是一个 String.
ComboBoxItem 是一个 Control.

你的例子中, ComboBox 的 SelectedValue 的类型应该对应 ComboBoxItem, 而你企图强制指定它为一个 String, 显然不行.
概念不清 :(

试试这个:
在 根元素加入:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
然后重新写过 ComboBox:
<ComboBox SelectedValue="Binding Path=DataType.Name, Mode=OneWay">
<sys:String>String</sys:String>
<sys:String>Boolean</sys:String>
<sys:String>Byte[]</sys:String>
</ComboBox>

then, you got it.

----
补充说明一下, 我这个与你的 ComboBox 的不同之处:
我的示例中, ComboBox 的每个 Item 是 String. SelectedValue 就是一个 string, 只是这个 String 默认的由 ComboBoxItem 来承载.
你的示例中, ComboBox 的每个 Item 是 ComboBoxItem, 这个 ComboBoxItem 的Content 值是 String. SelectedValue 是一个 ComboBoxItem. (由於它是 ComboBoxItem, 所以 wpf 不会再用一个 ComboBoxItem 来承载它.)

直观一点就是:
<ComboBox x:Name="cb1" SelectedIndex="0">
<ComboBoxItem Content="String"/>
</ComboBox>
<ComboBox x:Name="cb2" SelectedIndex="0">
<sys:String>String</sys:String>
</ComboBox>
MessageBox.Show(cb1.SelectedValue.GetType().ToString());
MessageBox.Show(cb2.SelectedValue.GetType().ToString());
答案应该是:
System.Windows.Controls.ComboBoxItem 和
System.String

Hope help.本回答被提问者和网友采纳

如何将通用项目添加到绑定到 WPF 中的集合的 ComboBox

【中文标题】如何将通用项目添加到绑定到 WPF 中的集合的 ComboBox【英文标题】:How do you add a generic item to a ComboBox bound to a collection in WPF 【发布时间】:2011-01-10 05:42:09 【问题描述】:

我在 WPF 应用程序中有一个 ComboBox,它绑定到 C# ViewModel 类中 Department 对象的 ObservableCollection。我想使用组合框按部门过滤另一个集合(现在确实适用)问题是我想在列表顶部添加一个附加选项“全部”。有没有正确的方法来做到这一点。让一个假部门感觉在很多方面都是错误的。

组合框

<ComboBox ItemsSource="Binding Path=Departments" 
          SelectedValue="Binding Path=DepartmentToShow , Mode=TwoWay" />

【问题讨论】:

【参考方案1】:

您可以使用 CompositeCollection 作为 ComboBox 的 ItemsSource 以包含“全部”选项。您需要将 CollectionContainer 的 Collection 属性设置为“部门对象的 ObservableCollection”。

<ComboBox >
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem>All</ComboBoxItem>
            <CollectionContainer x:Name="departmentCollection"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>

不确定这是否适合您的过滤情况...

【讨论】:

+1 哇,作为一名经验丰富的 WPF 程序员,我什至不知道CompositeCollection!搜索互联网时有各种解决方法,但没有提到这一点!难以置信... 是的,当我读到这篇文章时,我很惊讶。今天早上我一直在做一些调查,我认为它会成功。现在过滤是在构建 Linq 查询时完成的,所以我想我可以测试“全部”,如果没有选择,则迭代 peopleCollection。将来我计划重构并使用 CollectionViewSource 过滤视图而无需重新查询;我不确定这将如何工作,但对于这个问题,我有我的答案。谢谢! @Aviad 是的,这是一个不错的解决方案,但确实有点糟糕的是,您不能通过 DataContext 绑定到 Collection 属性,因为 CompositeCollection 不是 Freezable。这可以通过绑定到静态资源来解决... 这个问题的解决方案有一个例子说明如何以这种方式绑定***.com/questions/1189052/… 不是特别漂亮的IMO,但可以解决问题...... 以这种方式添加 ComboBoxitem 会引发 Horizo​​ntalContentAlignment 和 VerticalContentAlignment 绑定错误。有人对此有解决方案吗?【参考方案2】:

假设您有一个名为 MyCombo 的 ComboBox,一个名为 MyEntity 的实体与名为 MyDomainService 的 DomaineService 相关联。

别忘了

using System.ServiceModel.DomainServices.Client;

当然还有与您的实体和 DomainService 的网站一起使用效果很好

你调用了一个名为 :

void LoadEntities()

    MyDomainService_Context = new MyDomainService();
    EntityQuery<MyEntity > mQuery = null;

    mQuery = from q in _Context.GetMyDomainServiceQuery()
             select q;

    LoadOperation<MyEntity > loadOpLoadEntities = _Context.Load(mQuery, LoadOpLoadEntitiesCallBack, null);

然后在CallBack函数中:

void LoadOpLoadEntitiesCallBack(LoadOperation<MyEntity> loadOperation)

    if (loadOperation.Entities.Count() > 0)
    
        List<MyEntity> mList = new List<MyEntity>();
        MyEntity mE = new MyEntity();
        mE.Column1 = -1;
        mE.Column2 = "Default value";
        mList.Add(mE);

        for (int i = 0; i < loadOperation.Entities.Count(); i++)
        
            mList.Add(loadOperation.Entities.ToList()[i]);
        

        this.MyCombo.ItemsSource = mList.ToList();
    

【讨论】:

这是一个使用 Linq to SQL 的 MVVM WPF 应用程序。 Composite COllection 解决方案几年来一直运行良好,但感谢您的额外投入。

以上是关于wpf中如何实现Combobox作为ListView某列显示的主要内容,如果未能解决你的问题,请参考以下文章

带CheckBoxes的WPF ComboBox显示有关已检查项目的信息?

WPF ComboBox控件隐藏倒三角

如何将 ComboBox 的 SelectedItem 绑定到作为 ItemsSource 中项目副本的对象?

wpf combobox 页面上怎么绑定值

WPF的ComboBox数据绑定,使用Dictionary作为数据源

wpf如何根据输入信息动态生成treeview