6

グループを展開/折りたたむことができるように、各グループのエキスパンダーを表示している XAML に ItemsControl があります。IsExpandedプロパティの状態 (およびグループ ヘッダーの表示に関連するその他の設定)を保持したいと考えています。通常、プロパティを持つクラスがあり、これにバインドします。ただし、グループのデータ コンテキストはCollectionViewGroup. このクラスは、名前プロパティとグループ内のアイテムしか提供しないため、あまり役に立ちません (見出しだけが必要で、グループ内のアイテムの数またはそのただし、グループ ヘッダー UI の状態に関するカスタム データを保存するだけの場合はそうではありません)。私がやりたいのは、このクラスから派生し、他のプロパティを派生クラスに追加して、代わりにそれにバインドすることです。しかし、これを行う簡単な方法はないようです。グループ生成の詳細はすべて内部クラスに隠されているようで、非常にイライラします。誰かが自分自身を実装する道をたどりましたかICollectionView(したがって、おそらく他のすべての関連クラスも同様です)? すべてを複製するのは大変な作業のようですListCollectionViewカスタムCollectionViewGroupクラスを作成し、代わりにそれにバインドできるようにするだけです! ありがとう。

4

3 に答える 3

1

1 つの方法は、 を使用しMultiBindingてカスタム データとバインド時間を検索または計算することです。

グループ内の項目の特定の値の合計をヘッダーに表示するグループを作成しましDataGridた。グループ項目が変更されたときにこの合計を更新するために、カスタム多値コンバーターを使用して多値バインディングを作成しましItemCountた。グループ項目が変更され、合計が更新され、newsum 値が表示されます。

複数値コンバータ クラスのコードは次のとおりです。

Public Class UserBalanceConverter
Implements IMultiValueConverter

Private Function GetSubTotal(ByVal obj As CollectionViewGroup) As String

    Dim total As Decimal
    For Each objItem As Object In obj.Items
        If TypeOf objItem Is Account Then
            Dim a As Account = DirectCast(objItem, Account)
            Dim rate As Decimal = 1
            rate = 1 / ExchangeRatesInfo.GetExchangeRate(a.currencyCode.ToString)

            total += a.Balance * rate
        Else
            total += GetSubTotal(objItem)
        End If
    Next

    Return total.ToString("C")
End Function

Public Function Convert(ByVal value() As Object,
                        ByVal targetType As System.Type,
                        ByVal parameter As Object,
                        ByVal culture As System.Globalization.CultureInfo) _
         As Object Implements System.Windows.Data.IMultiValueConverter.Convert

    Dim cvg As CollectionViewGroup = CType(value(1), CollectionViewGroup)

    Return GetSubTotal(cvg)

End Function


Public Function ConvertBack(ByVal value As Object,
                            ByVal targetType() As System.Type,
                            ByVal parameter As Object,
                            ByVal culture As System.Globalization.CultureInfo) _
        As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack

    Throw New NotImplementedException

End Function

End Class

次に、XAML で、 GroupItem に使用されるスタイルで複数値コンバーターを使用します。

  <Style TargetType ="{x:Type GroupItem}" x:Key="UserGroupHeaderStyle">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander x:Name="exp" IsExpanded="False">
                            <Expander.Header>
                                <StackPanel >
                                    <TextBlock Text="{Binding Name}" />
                                    <StackPanel Orientation="Horizontal" >
                                        <TextBlock Text="{Binding ItemCount}">
                                        <TextBlock Text=" "/>
                                        <TextBlock Text="items" />
                                        <TextBlock Text=" "/>
                                        <TextBlock Text="Balance: " />
                                        <TextBlock>
                                            <TextBlock.Text>
                                                <MultiBinding Converter="{StaticResource UserBalanceConverter}">
                                                    <Binding Path="ItemCount"/>
                                                    <Binding />
                                                </MultiBinding>
                                            </TextBlock.Text>
                                        </TextBlock>
                                    </StackPanel>
                                </StackPanel>
                            </Expander.Header>
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

スタイルを DataGrid に適用して終了します。

<DataGrid.GroupStyle>
     <GroupStyle ContainerStyle="{StaticResource UserGroupHeaderStyle}">
             <GroupStyle.Panel>
                   <ItemsPanelTemplate>
                           <DataGridRowsPresenter/>
                   </ItemsPanelTemplate>
             </GroupStyle.Panel>
     </GroupStyle>
 </DataGrid.GroupStyle>

XAML のリソース セクションで変換クラスを宣言することも忘れないでください。

  <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
             <local:UserBalanceConverter x:Key="UserBalanceConverter"/>
        </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>

Et Voilà ! それは魅力のように機能します!

HTH

于 2013-01-17T17:19:02.063 に答える
0

簡単な方法は、CollectionViewGroup を、IsExpanded などの追加の必要な表示プロパティを提供する別の ViewModel クラスにラップすることです。私が苦労して学んだ教訓は、ビジネス データに合わせて xaml / ビューを曲げないことでした。代わりに、UI の要件に合わせてビジネス データを曲げたり、ラップしたり、変換したりします。

于 2012-11-06T07:13:09.910 に答える
0

Cédricの提案に多少似ていますが、一見MVVMの方法で、この問題を正確に解決することができました(つまり、にバインドします):IsExpanded

<ControlTemplate TargetType="GroupItem">
    <TreeViewItem IsExpanded="{Binding Items[0].IsGroupExpanded, Mode=TwoWay}">
        <TreeViewItem.Header>
            <TextBlock Text="{Binding Name}" />
        </TreeViewItem.Header>
        <TreeViewItem.Items>
            <ItemsPresenter />
        </TreeViewItem.Items>
    </TreeViewItem>
</ControlTemplate>

ItemViewModel.IsGroupExpandedセッターとゲッターの両方が にリダイレクトされGroup.IsExpandedます。

デフォルトでバインドされているように見えるためMode=TwoWay、指定する必要があることに注意してください。IsExpandedOneWay

于 2016-01-07T21:18:05.800 に答える