2013-04-28 122 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 = 「假」 組合框。