2012-11-05 2 views
6

XAML에서 각 그룹에 대해 확장기를 표시하고있어 그룹을 확장/축소 할 수있는 ItemsControl이 있습니다. IsExpanded 속성의 상태와 그룹 머리글 표시와 관련된 다른 설정을 유지하려고합니다. 일반적으로 속성이있는 클래스가 있고 바인딩되어 있습니다. 그러나 그룹의 데이터 컨텍스트는 CollectionViewGroup입니다. 이제이 클래스는 Name 속성과 그룹의 항목 만 제공하기 때문에별로 도움이되지 않습니다 (그룹의 항목 수 또는 그룹의 항목 수에 따라 일종의 메트릭을 표시 할 수 있습니다. 그룹 머리글 UI의 상태에 대한 사용자 지정 데이터를 저장하려는 경우가 아니라). 내가하고 싶은 것은이 클래스에서 파생되고 다른 속성을 파생 클래스에 추가하고 그 대신 바인딩하는 것입니다. 그러나 이것을하기위한 쉬운 방법이없는 것 같습니다. 그룹 생성에 대한 모든 세부 사항은 매우 실망스러운 내부 수업에 숨어있는 것처럼 보입니다. 누구든지 ICollectionView을 구현하는 경로를 따라갔습니다 (따라서 다른 모든 관련 클래스도 마찬가지일까요?). ListCollectionView에있는 모든 것을 복제하는 대규모 작업처럼 사용자 정의 CollectionViewGroup 클래스를 생성하고이를 대신 바인딩 할 수 있습니다! 감사.사용자 지정 데이터를 CollectionViewGroup과 연결하는 방법?

답변

0

간단한 접근법은 CollectionViewGroup을 IsExpanded와 같은 추가 디스플레이 속성을 제공하는 다른 ViewModel 클래스로 래핑하는 것입니다. 내가 배운 교훈은 비즈니스 데이터와 일치하도록 xaml/view를 구부리지 않는 것이 었습니다. 대신 UI의 요구 사항에 맞게 비즈니스 데이터를 구부리기/감싸기 또는 변환하십시오.

+3

예를 들어 설명해 주시겠습니까? –

1

한 가지 방법은 MultiBinding을 사용하여 사용자 지정 데이터와 바인딩 시간을 찾거나 계산하는 것입니다.

DataGrid 그룹의 항목 값의 합계를 헤더에 표시하는 그룹으로 그룹 항목을 변경할 때이 합계를 업데이트했습니다. 사용자 지정 다중 값 변환기로 다중 값 바인딩을 만들었습니다. 다중 값 바인딩은 ItemCount으로 바인딩됩니다. 속성을 사용하면 그룹 항목이 변경 될 때 알림을 받고 합계를 업데이트하고 뉴스um 값을 표시 할 수 있습니다. 당신이 GroupItem에 사용되는 스타일로 다중 변환기를 사용 XAML에서 그런

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 

: 여기

은 다중 값 변환기 클래스의 코드에 스타일을 적용와

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

또한 변환 클래스 i를 선언하는 것을 잊지 마십시오. n XAML의 리소스 섹션 :

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

Et Voilà! 그것은 매력처럼 작동합니다!

HTH

+0

이것은 OP 질문에 어떻게 대답합니까? 그는 IsExpanded 값을 유지하는 방법을 물었고 질문에서 제외시킨 항목의 메트릭을 생성하지 않았습니다. – Firo

0

나는 를 해결할 수 있었다 정확하게이 문제 겉으로는 더 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 setter 및 getter는 모두 Group.IsExpanded으로 리디렉션됩니다.

IsExpanded은 기본적으로 OneWay으로 제한되어 있으므로 Mode=TwoWay을 지정해야합니다.