2013-04-28 121 views
1

我有一个ListViewDataTemplat e由ComboBox和一些TextBox es组成。 ComboBox绑定到映射到CollectionViewSource的Collection。 ListView可以有任意数量的行。在列表视图中将组合框绑定到组合框

问题是在一个ComboBox中选择一个项目会将它们全部更改。我确实希望它们都被填充相同的内容,但要能够独立设置。

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

<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> 

ListView定义为:

<ListView Grid.Column="0" x:Name="lstChildren" Margin="20,30,0,0" ItemsSource="{Binding Path=Items}" Style="{StaticResource ChildListViewStyle}"/> 

编辑:

在相关联的类被发现以下

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 
.... 

回答

0

您需要将CollectionViewSource转换为DataTemplate。要强制所有组合框项使用相同的源集合,我认为你可以尝试两件事情:

一个 - 使用相对源来接从ListViewDataContext

... 
<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> 
... 

更新ChildAccounts

以上方法可见于This样本我放在一起。请注意,ChildAccount的视图模型只是ObservableCollection<T>,这是因为我们没有根据ListBoxItem收集新集合,而是像您在问题中要求的那样分享em。

如果您ChildAccounts属性实际上是喜欢说的“注释”属性,你必须每一个ListBoxItem一个ChildAccounts属性对象,只是改变

<CollectionViewSource x:Key="ChildGroupedData" 
         Source="{Binding RelativeSource={RelativeSource FindAncestor, 
                     AncestorType={x:Type ListView}}, 
              Path=DataContext.ChildAccounts}"> 

<CollectionViewSource x:Key="ChildGroupedData" 
         Source="{Binding ChildAccounts}"> 

,它应该工作以及。不过,您现在每ListBoxItem有一个ChildAccounts集合,并且不会共享其源。

主要的是定义DataTemplate中的CollectionViewSource。下载附件中的示例并自行尝试并检查具体内容。

- 有ChildAccounts作为一个静态变量

... 
<Grid.Resources> 
    <CollectionViewSource x:Key="ChildGroupedData" 
         Source="{x:Static local:ChildAccounts}"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="group" /> 
    </CollectionViewSource.GroupDescriptions> 
    </CollectionViewSource> 
</Grid.Resources> 
... 
+0

谢谢。尝试第一个,它不起作用。组合框是空的。无法获得第二个编译。它说'找不到成员'ChildAccounts'的目标类型'和'l:ChildAccounts成员无效,因为它没有合格的类型名称。我将其更改为{x:Static l:ItemView.ChildAccounts} - 然后仅获取一个错误 - 无法在类型“ItemView”上找到成员'ChildAccounts'。我声明了xmlns:l =“clr-namespace:WpfAccounts”以允许访问命名空间。在代码中包含ChildAccounts的类称为ItemView。谢谢。 Andy – 2013-04-30 00:50:54

+0

@AndyPowell第一种方法适用于我。你可以请张贴您的视图模型代码为ChuldAccounts属性和项目属性。如果需要修剪代码。保留名称空间和类结构。我把我的工作解决方案发布到Dropbox上,所以你可以尝试一下。与ListView绑定的属性Items是ItemView类对象的可观察集合吗? – Viv 2013-04-30 06:24:37

+0

@AndyPowell我已经在选项1后更新了我的答案,并附有链接以下载显示选项1工作的示例项目。下载它,看看你的VM属性声明是如何不同的。我在答案中提到的选项2是针对静态变量的。如果你的财产不是静态的,你不能使用它。 – Viv 2013-04-30 07:04:15

0

您可以添加设置IsSynchronizedWithCurrentItem = “假” 组合框。