Wpf 将集合绑定到Listview中的ComboBox

Wpf 将集合绑定到Listview中的ComboBox,wpf,xaml,listview,collections,combobox,Wpf,Xaml,Listview,Collections,Combobox,我有一个列表视图,它的数据模板e由一个组合框和一些文本框组成。 组合框绑定到映射到CollectionViewSource的集合。 列表视图可以有任意数量的行 问题是在一个组合框中选择一个项目会更改所有项目。我确实希望它们都填充相同的内容,但能够独立设置 参考资料部分包含以下内容: <CollectionViewSource Source="{Binding ChildAccounts}" x:Key="ChildGroupedData"> <Colle

我有一个
列表视图
,它的
数据模板
e由一个
组合框
和一些
文本框
组成。 组合框绑定到映射到CollectionViewSource的集合。
列表视图可以有任意数量的行

问题是在一个
组合框中选择一个项目会更改所有项目。我确实希望它们都填充相同的内容,但能够独立设置

参考资料部分包含以下内容:

    <CollectionViewSource Source="{Binding ChildAccounts}" x:Key="ChildGroupedData">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="group"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

    <!-- Template for each child item in ListView -->
    <DataTemplate x:Key="ChildTemplate">
        <Grid>
            <Grid.ColumnDefinitions>                    
                <ColumnDefinition Width="90"/>
                <ColumnDefinition Width="130"/>
                <ColumnDefinition Width="90"/>
                <ColumnDefinition Width="90"/>
                <ColumnDefinition Width="90"/>
                <ColumnDefinition Width="210"/>
            </Grid.ColumnDefinitions>                
            <Label Grid.Column="0" Content="Account" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="{StaticResource CustomWhite}" FontSize="14" Width="80"/>
            <ComboBox Grid.Column="1" SelectedValue="{Binding Path=accFrom}" ItemsSource="{Binding Source={StaticResource ChildGroupedData}}" ItemTemplate="{StaticResource AccountTemplate}" SelectedValuePath="ID" Width="120" Style="{StaticResource RoundedComboBox}" HorizontalAlignment="Left" VerticalAlignment="Center">
                <ComboBox.GroupStyle>
                    <GroupStyle ContainerStyle="{StaticResource CustomExpanderComboGroupItemStyle}" HeaderTemplate="{StaticResource GroupHeader}"/>
                </ComboBox.GroupStyle>
            </ComboBox>
            <Label Grid.Column="2" Content="Amount" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="{StaticResource CustomWhite}" FontSize="14" Width="80"/>
            <TextBox Grid.Column="3" Text="{Binding Path=amount, StringFormat='#,##0.00'}" Style="{StaticResource RoundedTextBox}" Width="80" HorizontalAlignment="Left" VerticalAlignment="Center"/>
            <Label Grid.Column="4" Content="Comment" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="{StaticResource CustomWhite}" FontSize="14" Width="80"/>
            <TextBox Grid.Column="5" Text="{Binding Path=comment}" Style="{StaticResource RoundedTextBox}" Width="200" HorizontalAlignment="Left" VerticalAlignment="Center"/>
        </Grid>
    </DataTemplate>

    <!-- ListView template -->
    <Style x:Key="ChildListViewStyle" TargetType="{x:Type ListView}">
        <Setter Property="ItemTemplate" Value="{DynamicResource ChildTemplate}"/>
        <Setter Property="Background" Value="{StaticResource CustomBackground}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="Margin" Value="10,10,10,10"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Padding" Value="0,0,50,0"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Style.Resources>
            <!-- Makes selection invisible when focus lost -->
            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{StaticResource CustomBackgroundC}"/>
        </Style.Resources>
    </Style>
编辑:

在关联的类中可以找到以下内容

Imports System.Data
Imports System.Data.OleDb
Imports System.Collections.ObjectModel
Imports System.ComponentModel

Class ItemView
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged(ByVal info As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub

....

Private _ChildAccounts As ObservableCollection(Of AccountEntry)
Public Property ChildAccounts As ObservableCollection(Of AccountEntry)
    Get
        Return _ChildAccounts
    End Get
    Set(value As ObservableCollection(Of AccountEntry))
        _ChildAccounts = value
    End Set
End Property

....

Private Sub ItemView_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized

    Dim dsacmd As OleDbDataAdapter
    Dim dsa As New DataSet
    Dim dva As DataView
    Dim strSelect As String

    Try
        ' ** Open a connection to the database.        
        cn = New OleDbConnection(strConnection)
        cn.Open()

        Me.DataContext = Me

        strSelect = "SELECT Accounts.ID, Accounts.deleted, Accounts.accType, Accounts.currency as curr, IIf([Currencies.ID]=1,Accounts.comment,Accounts.comment & "" ("" & Currencies.symbol & "")"") AS comment, Currencies.comment AS currS FROM Currencies INNER JOIN Accounts ON Currencies.ID = Accounts.currency"
        dsacmd = New OleDbDataAdapter(strSelect, cn)
        dsacmd.Fill(dsa, "Accounts")
        dva = New DataView(dsa.Tables("Accounts"))
        dva.RowFilter = "accType=" & cVirtual.ToString & " AND deleted=False"
        dva.Sort = "curr, comment"
        ChildAccounts = New ObservableCollection(Of AccountEntry)(dva.ToTable.AsEnumerable().[Select](Function(i) New [AccountEntry](i("ID"), i("currS").TrimEnd(" "), i("comment"))))

....

Private Sub DisplayItem()

    ....

            strSelect = ""
            Dim Relations As Collection(Of Relation) = GetRelations(ID)
            For Each r As Relation In Relations
                strSelect &= "ID=" & r.ID.ToString & " OR "
            Next
            If strSelect <> "" Then strSelect = "SELECT * FROM Items WHERE " & strSelect.Substring(0, strSelect.Length - 4)
            If strSelect <> "" Then
                dsrcmd = New OleDbDataAdapter(strSelect, cn)
                dsr.Clear()
                dsrcmd.Fill(dsr, "Items")
                lstChildren.DataContext = dsr
            End If
....
导入系统数据
导入System.Data.OleDb
导入System.Collections.ObjectModel
导入System.ComponentModel
类项目视图
实现INotifyPropertyChanged
公共事件PropertyChanged为PropertyChangedEventHandler实现INotifyPropertyChanged.PropertyChanged
私有子NotifyPropertyChanged(ByVal信息作为字符串)
RaiseEvent PropertyChanged(我,新PropertyChangedEventArgs(信息))
端接头
....
作为可观察集合的私人账户(账户分录)
公共财产子账户作为可观察集合(会计分录)
得到
返回儿童帐户
结束
设置(值为(会计分录的)可观察集合)
_儿童账户=价值
端集
端属性
....
Private Sub ItemView_Initialized(发送者作为对象,e作为事件参数)处理我。Initialized
作为OLEDB数据适配器的Dim dsacmd
Dim dsa作为新数据集
Dim dva作为数据视图
Dim strSelect As字符串
尝试
'**打开与数据库的连接。
cn=新的OLEDB连接(strConnection)
cn.Open()
Me.DataContext=Me
strSelect=“选择Accounts.ID,Accounts.deleted,Accounts.acktype,Accounts.currency作为货币,IIf([currences.ID]=1,Accounts.comment,Accounts.comment&(”“¤ces.symbol&”“)作为注释,currences.comment作为货币从货币内部加入accounters ON currences.ID=Accounts.currency”
dsacmd=新的OleDbDataAdapter(strSelect,cn)
dsacmd.Fill(dsa,“账户”)
dva=新数据视图(dsa.Tables(“Accounts”))
dva.RowFilter=“accType=“&cVirtual.ToString&”和deleted=False”
dva.Sort=“curr,comment”
ChildAccounts=New ObservableCollection(Of AccountEntry)(dva.ToTable.AsEnumerable()[Select](函数(i)New[AccountEntry](i(“ID”)、i(“currS”)、TrimEnd(“”)、i(“注释”))
....
专用子项()
....
strSelect=“”
将关系设置为集合(关系的)=GetRelations(ID)
对于关系中的每个r作为关系
strSelect&=“ID=”&r.ID.ToString&“或”
下一个
如果是strSelect“”,则strSelect=“SELECT*FROM Items WHERE”&strSelect.Substring(0,strSelect.Length-4)
如果选择“”则
dsrcmd=新的OLEDB数据适配器(strSelect,cn)
dsr.Clear()
dsrcmd.填充(dsr,“项目”)
lstChildren.DataContext=dsr
如果结束
....

您需要将您的
CollectionViewSource
移动到
DataTemplate
中。要强制所有combobox项使用相同的源集合,我认为您可以尝试两种方法:

One-使用相对源从
ListView
DataContext

...
<Grid.Resources>
  <CollectionViewSource x:Key="ChildGroupedData"
                        Source="{Binding RelativeSource={RelativeSource FindAncestor,
                                                                        AncestorType={x:Type ListView}},
                                          Path=DataContext.ChildAccounts}">
    <CollectionViewSource.GroupDescriptions>
      <PropertyGroupDescription PropertyName="group" />
    </CollectionViewSource.GroupDescriptions>
  </CollectionViewSource>
</Grid.Resources>
...


您可以将set IsSynchronizedWithCurrentItem=“False”添加到组合框中。

谢谢。尝试了第一个,但不起作用。组合框是空的。无法获取要编译的第二个。它表示“在目标类型上找不到成员“ChildAccounts”,并且“l:ChildAccounts成员无效,因为它没有限定的类型名。”。我将其更改为{x:Static l:ItemView.ChildAccounts}-然后只会得到一个错误-在类型“ItemView”上找不到成员“ChildAccounts”。我已声明xmlns:l=“clr namespace:WpfAccounts”以允许访问该命名空间。代码中包含ChildAccounts的类称为ItemView。谢谢Andy@AndyPowell第一种方法对我来说很好。您可以发布ChuldAccounts属性和Items属性的视图模型代码吗。如果需要,请修剪代码。保留名称空间和类结构。我也会把我的工作方案贴到Dropbox上,这样你可以试一下。绑定到ListView的属性项是ItemView类对象的可观察集合吗?@AndyPowell我已经更新了选项1之后的答案,并提供了一个链接,以下载显示选项1工作的示例项目。下载它,看看您的VM属性声明有何不同。我在回答中提到的选项2是针对静态变量的。如果你的财产不是静态的,你就不能使用它。谢谢。我今晚会去看的。我不认为我在使用ViewModel(但肯定会从您的示例中学习)。ChildAccounts在ItemView类中声明为ObservableCollection(of Account)的公共属性。今晚将用代码更新问题。我想我可能已经破解了<代码>
我认为很有效!
...
<Grid.Resources>
  <CollectionViewSource x:Key="ChildGroupedData"
                        Source="{Binding RelativeSource={RelativeSource FindAncestor,
                                                                        AncestorType={x:Type ListView}},
                                          Path=DataContext.ChildAccounts}">
    <CollectionViewSource.GroupDescriptions>
      <PropertyGroupDescription PropertyName="group" />
    </CollectionViewSource.GroupDescriptions>
  </CollectionViewSource>
</Grid.Resources>
...
<CollectionViewSource x:Key="ChildGroupedData"
                        Source="{Binding RelativeSource={RelativeSource FindAncestor,
                                                                        AncestorType={x:Type ListView}},
                                          Path=DataContext.ChildAccounts}">
<CollectionViewSource x:Key="ChildGroupedData"
                        Source="{Binding ChildAccounts}">
...
<Grid.Resources>
  <CollectionViewSource x:Key="ChildGroupedData"
                        Source="{x:Static local:ChildAccounts}">
    <CollectionViewSource.GroupDescriptions>
      <PropertyGroupDescription PropertyName="group" />
    </CollectionViewSource.GroupDescriptions>
  </CollectionViewSource>
</Grid.Resources>
...