WPF DataGrid常用屬性記錄



組件常用方法:

BeginEdit:使DataGrid進入編輯狀態。

CancelEdit:取消DataGrid的編輯狀態。

CollapseRowGroup:閉合DataGrid的行分組。

CommitEdit:確認DataGrid的編輯完成。

ExpandRowGroup:展開DataGrid的行分組。

GetGroupFromItem:從具體Item中得到分組。

ScrollIntoView:滾動DataGrid視圖。

 

組件常用屬性:

AlternatingRowBackground:獲取或設置一個筆刷用來描繪DataGrid奇數行的背景。

AreRowDetailsFrozen:獲取或設置一個值用來判斷是否凍結每行內容的詳細信息。

AreRowGroupHeadersFrozen:獲取或設置一個值用來判斷是否凍結分組行的頭部。

AutoGenerateColumns:獲取或設置一個值用來判斷是否允許自動生成表列。

CanUserReorderColumns:獲取或設置一個值用來判斷是否允許用戶重新排列表列的位置。

CanUserSortColumns:獲取或設置一個值用來判斷是否允許用戶按列對表中內容進行排序。

CellStyle:獲取或設置單元格的樣式。

ColumnHeaderHeight:獲取或設置列頭的高度。

ColumnHeaderStyle:獲取或設置列頭的樣式。

Columns:獲取組件中包含所有列的集合。

ColumnWidth:獲取或設置列寬。

CurrentColumn:獲取或設置包含當前單元格的列。

CurrentItem:獲取包含當前單元格且與行綁定的數據項。

DragIndicatorStyle:獲取或設置當拖曳列頭時的樣式。

DropLocationIndicatorStyle:獲取或設置呈現列頭時的樣式。

FrozenColumnCount:獲取或設置凍結列的個數。

GridLinesVisibility:獲取或設置網格線的顯示形式。

HeadersVisibility:獲取或設置行頭及列頭的顯示形式。

HorizontalGridLinesBrush:獲取或設置水平網格線的筆刷。

HorizontalScrollBarVisibility:獲取或設置水平滾動條的顯示樣式。

IsReadOnly:獲取或設置DataGrid是否為只讀。

MaxColumnWidth:獲取或設置DataGrid的最大列寬。

MinColumnWidth:獲取或設置DataGrid的最小列寬。

RowBackground:獲取或設置用於填充行背景的筆刷。

RowDetailsTemplate:獲取或設置被用於顯示行詳細部分的內容的模板。

RowDetailsVisibilityMode:獲取或設置一個值用以判定行詳細部分是否顯示。

RowGroupHeaderStyles:獲取呈現行分組頭部的樣式。

RowHeaderStyle:獲取或設置呈現行頭的樣式。

RowHeaderWidth:獲取或設置行頭的寬度。

RowHeight:獲取或設置每行的高度。

RowStyle:獲取或設置呈現行時的樣式。

SelectedIndex:獲取或設置當前選中部分的索引值。

SelectedItem:獲取或設置與當前被選中行綁定的數據項。

SelectedItems:獲取與當前被選中的各行綁定的數據項們的列表(List)。

SelectionMode:獲取或設置DataGrid的選取模式。

VerticalGridLinesBrush:獲取或設置垂直網格線的筆刷。

VerticalScrollBarVisibility:獲取或設置垂直滾動條的顯示樣式。

 

組件常用事件:

BeginningEdit:發生於一個單元格或行進入編輯模式之前。

CellEditEnded:發生於一個單元格編輯已被確認或取消。

CellEditEnding:發生於一個單元格正在結束編輯時。

CurrentCellChanged:發生於一個單元格成為當前單元格時。

PreparingCellForEdit:發生於在DataGridTemplateColumn下的單元格進入編輯模式時。

SelectionChanged:發生於當SelectedItem或SelectedItems屬性值改變時。

 

1.DataGrid隔行變色

RowBackground和AlternatingRowBackground設置一排交替行的背景。AlternationCount是將用於行的樣式或顏色的總數

1 <DataGrid Name="dg" RowHeaderWidth="50" AlternationCount="2" AlternatingRowBackground="#F4F4F4"  AutoGenerateColumns="False" Grid.Row="1" HeadersVisibility="All"  Margin="4" >
2                     <DataGrid.Columns>
3                         <DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
4                     </DataGrid.Columns>
5                 </DataGrid>

如果設置AlternatingRowBackground刷,將被分配到行,其中(rownumber%AlternationIdex)== 1

 1 <Style x:Key="DataGridDemoRowStyle"  
 2 TargetType="{x:Type Custom:DataGridRow}">
 3 <Style.Triggers>
 4 <Trigger Property="AlternationIndex" Value="2" >
 5  <Setter Property="Background" Value="{StaticResource RowBackgroundAlternationIndex2Brush}" />
 6 </Trigger>
 7 <Trigger Property="AlternationIndex" Value="3">
 8 <Setter Property="Background" Value="{StaticResource RowBackgroundAlternationIndex3Brush}" />
 9 </Trigger>
10 </Style.Triggers>
11 </Style>

請注意對於上面的樣式,有目的的,我只覆蓋AlternationIndex= 2,3。對於AlternationIndex= 0時,它使用RowBackground。
對於AlternationIndex= 1,它使用從DataGrid中AlternatingRowBackground的。

 

2.DataGrid的ErrorTemplate屬性

 1 <Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}">
 2         <Setter Property="Background" Value="Transparent" />
 3         <Setter Property="SnapsToDevicePixels" Value="true"/>
 4         <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
 5         <Setter Property="ValidationErrorTemplate">
 6             <Setter.Value>
 7                 <ControlTemplate>
 8                     <TextBlock Margin="2,0,0,0" VerticalAlignment="Center" Foreground="#FFdc000c" Text="!" />
 9                 </ControlTemplate>
10             </Setter.Value>
11         </Setter>
12 </Style>

上面這段XAML設置了DataGridRow的ValidationErrorTemplate為RowHeader通過模板

 1 <Style x:Key="{x:Type DataGridRowHeader}" TargetType="{x:Type DataGridRowHeader}">
 2         <Setter Property="Background" Value="{DynamicResource DataGridHeaderBackground}" />
 3         <Setter Property="Foreground" Value="{DynamicResource DataGridHeaderForeground}" />
 4         <Setter Property="BorderBrush" Value="{DynamicResource DataGridGridLines}" />
 5         <Setter Property="BorderThickness" Value="0,0,0,1" />
 6         <Setter Property="Width" Value="16"/>
 7         <Setter Property="Template">
 8             <Setter.Value>
 9                 <ControlTemplate TargetType="{x:Type DataGridRowHeader}">
10                     <Grid>
11                         <Border Background="{TemplateBinding Background}"
12                                 BorderBrush="{TemplateBinding BorderBrush}"
13                                 BorderThickness="{TemplateBinding BorderThickness}"
14                                 Padding ="{TemplateBinding Padding}">
15 
16                             <StackPanel Orientation="Horizontal">
17                                 <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
18                                 <Control SnapsToDevicePixels="false"
19                                          Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilityConverter}}"
20                                          Template="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=ValidationErrorTemplate}" />
21                             </StackPanel>
22                         </Border>
23                         <Thumb x:Name="PART_TopHeaderGripper"
24                                VerticalAlignment="Top"
25                                Style="{StaticResource RowHeaderGripperStyle}"/>
26                         <Thumb x:Name="PART_BottomHeaderGripper"
27                                VerticalAlignment="Bottom"
28                                Style="{StaticResource RowHeaderGripperStyle}"/>
29                     </Grid>
30                 </ControlTemplate>
31             </Setter.Value>
32         </Setter>
33 
34         <Style.Triggers>
35             <Trigger Property="IsMouseOver" Value="True">
36                 <Setter Property="Background" Value="{DynamicResource DataGridHeaderBackgroundHover}" />
37                 <Setter Property="Foreground" Value="{DynamicResource DataGridHeaderForegroundHover}" />
38             </Trigger>
39             <Trigger Property="IsPressed" Value="True">
40                 <Setter Property="Background" Value="{DynamicResource DataGridHeaderBackgroundPressed}" />
41                 <Setter Property="Foreground" Value="{DynamicResource DataGridHeaderForegroundPressed}" />
42             </Trigger>
43             <Trigger Property="IsRowSelected" Value="True">
44                 <Setter Property="Background" Value="{DynamicResource DataGridHeaderBackgroundSelected}" />
45                 <Setter Property="Foreground" Value="{DynamicResource DataGridHeaderForegroundSelected}" />
46             </Trigger>
47         </Style.Triggers>
48     </Style>

主對於錯誤驗證主要是 當有錯誤的時候Control顯示,並獲取上面設置的DataGridRow的錯誤驗證模板為Control的模板,當沒有錯誤時就隱藏作為驗證顯示的Control

3.DataGrid 視圖(排序、過濾、分組)

CollectionView介紹

事實上當你將后台數據列表綁定到一個列表控件時,WPF為了默默地在數據列表和列表控件之間增加了層稱為CollectionView(列表視圖)的東西,其支持很多高級操作,比如排序,分組,過濾等.這樣我們就可以將這個過程分成3個部分來看:數據列表(維持着后台數據),列表視圖(維持着一些附加狀態,比如"當前項","排序"等),列表控件(負責對CollectionView的呈現,而不是對Collection)

1 CollectionView cv = new CollectionView(myList); 2 3 this.listBox.ItemsSource = cv; 

CollectionViewSource介紹

CollectionViewSource是CollectionView的一個XAML代理,意思就是說CollectionView不能在XAML中使用,如果希望在XML將CollectionView綁定到某個列表控件,那么請使用CollectionViewSource.它與CollectionView的基本關系是"HAS A". CollectionViewSource擁有一個CollectionView類型的View屬性來指定其對應的CollectionView對象,與之對應的,其還有一個Source屬性,來指明數據來源.一個簡單的流程是:將數據列表綁定到CollectionViewSource的Source屬性,然后將列表控件的ItemsSource屬性綁定到CollectionViewSource的View屬性.為什么不直接將列表控件的ItemSource屬性綁定到數據列表呢,這取決於你是否需要查找到該CollectionViewSource進而查找到其View來進行視圖操作(比如排序,導航等).這可能說得有些混亂了.看看下面的例子:

 

 1 <Window.Resources>
 2 
 3          <XmlDataProvider x:Key="Employees" XPath="/Employees/*">
 4              <x:XData>
 5                  <Employees xmlns="">
 6                      <Employee Name="Terry Adams" Type="FTE" EmployeeNumber="1" />
 7                      <Employee Name="Claire O&apos;Donnell" Type="FTE" EmployeeNumber="12345" />
 8                      <Employee Name="Palle Peterson" Type="FTE" EmployeeNumber="5678" />
 9                      <Employee Name="Amy E. Alberts" Type="CSG" EmployeeNumber="99222" />
10                      <Employee Name="Stefan Hesse" Type="Vendor" EmployeeNumber="-" />
11                  </Employees>
12              </x:XData>
13          </XmlDataProvider>
14 
15          <DataTemplate  DataType="Employee">
16              <TextBlock Text="{Binding XPath=@Name}" />
17          </DataTemplate>
18          
19      </Window.Resources>
20 
21      <StackPanel>
22          <ListBox ItemsSource="{Binding Source={StaticResource Employees}}"/>
23      </StackPanel>

 

  上面的例子中,我們按照傳統的方式,將ListBox的ItemsSource綁定到一個XMLDataProvider上,工作得很好,后來我們發現WPF中可以利用CollectionView來實現列表排序,當然這種排序我們希望僅僅是在表現層,所以我們決定我XAML來做.當在實際改造這段代碼的過程中,我們傷透了腦子,因為要在XAML中為我們的數據找到CollectionView對象並非易事.

 

  事實上,我們僅僅需要改變一下數據綁定的流程就可以了.我們將數據與CollectionViewSource關聯,然后CollectionViewSource與列表控件相關聯,然后我們就可以在CollectionViewSource插入我們任何想要的排序方式了.

 

 1 <Window.Resources>
 2 
 3          <XmlDataProvider x:Key="Employees" XPath="/Employees/*">
 4              <x:XData>
 5                  <Employees xmlns="">
 6                      <Employee Name="Terry Adams" Type="FTE" EmployeeNumber="1" />
 7                      <Employee Name="Claire O&apos;Donnell" Type="FTE" EmployeeNumber="12345" />
 8                      <Employee Name="Palle Peterson" Type="FTE" EmployeeNumber="5678" />
 9                      <Employee Name="Amy E. Alberts" Type="CSG" EmployeeNumber="99222" />
10                      <Employee Name="Stefan Hesse" Type="Vendor" EmployeeNumber="-" />
11                  </Employees>
12              </x:XData>
13          </XmlDataProvider>
14          
15          <CollectionViewSource  x:Key="cvs" Source="{Binding Source={StaticResource Employees}, XPath=/Employees/*}">
16              <CollectionViewSource.SortDescriptions>
17                 <!--在這里插入排序描述-->
18              </CollectionViewSource.SortDescriptions>
19              <CollectionViewSource.GroupDescriptions>
20                  <!--在這里插入分組描述-->
21              </CollectionViewSource.GroupDescriptions>
22          </CollectionViewSource>
23          
24          <DataTemplate  DataType="Employee">
25              <TextBlock Text="{Binding XPath=@Name}" />
26          </DataTemplate>
27          
28      </Window.Resources>
29 
30      <StackPanel>
31          <ListBox ItemsSource="{Binding Source={StaticResource cvs}}" x:Name="lb"/>
32      </StackPanel>

 

默認的數據集視圖供參考:

集合數據 默認視圖 注釋

IEnumerable

CollectionView

無法對項進行分組。

IList

ListCollectionView

最快。

IBindingList

BindingListCollectionView

 

 

public partial class Window1 : Window
    {

        private void buttonPrevious_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView view = GetFamilyView();
            view.MoveCurrentToPrevious();
        }

        private void buttonNext_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView view = GetFamilyView();
            view.MoveCurrentToNext();
        }

        ICollectionView GetFamilyView()
        {
            People people = this.FindResource("Family") as People;
            return CollectionViewSource.GetDefaultView(people);
        }

    }

 

  • 過濾篩選

同時為該排序按鈕提供點擊事件如下: 

 

 1 private void buttonFilter_Click(object sender, RoutedEventArgs e)
 2         {
 3             ICollectionView view = GetFamilyView();
 4             view.Filter = delegate(object target)
 5                 {
 6                     return ((Person)target).Age > 25;
 7                 };
 8             //view.Filter = new Predicate<object>(delegate(object target)
 9             //    {
10             //        return ((Person)target).Age > 25;
11             //    });
12         }

過濾比較簡單,不在贅述。在這里只要理解Predicate<object>型別這個委托變量Filter就行了。視圖里面的每一項滿足條件的返回出來

  • 分組

獲取數據源視圖,在分組描述里加上需要分組的屬性分組描述,這里需要分組的是Age

1 private void buttonGroup_Click(object sender, RoutedEventArgs e)
2         {
3             ICollectionView view = GetFamilyView();
4             view.GroupDescriptions.Add(new PropertyGroupDescription("Age"));
5         }

接下來是開啟GroupStyle,並設置GroupStyle的樣式就可以了

注意:在GroupStyle中綁定的Name不是指Person中的Name,而是view.GroupDescriptions.Add(new PropertyGroupDescription("Age"));中指定的這個Age。 

   上文也說了,這是一種最簡單的分組,在實際應用中,分組往往要復雜的多。比如以年齡分組來說,就不可能像上文中一樣,以一歲做為一組。現在,我們來實現如下的分組要求: 

   0-30:年輕; 

   30-60:中年; 

   >60:老年; 

   所有的自定義分組器都需要實現接口IValueConverter,如下: 

 1 class AgeToRangeConver: IValueConverter
 2     {
 3 
 4         #region IValueConverter 成員
 5 
 6         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 7         {
 8             int iValue = (int)value;
 9             if (0 < iValue && iValue <= 30)
10             {
11                 return "年輕";
12             }
13             else if (30 < iValue && iValue <= 60)
14             {
15                 return "中年";
16             }
17             else
18             {
19                 return "老年";
20             }
21         }
22 
23         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
24         {
25             throw new NotImplementedException();
26         }
27 
28         #endregion
29     }

然后,點擊事件修改為: 

1 private void buttonGroup_Click(object sender, RoutedEventArgs e)
2         {
3             ICollectionView view = GetFamilyView();
4             view.GroupDescriptions.Add(new PropertyGroupDescription("Age", new AgeToRangeConver()));
5         }

可以看到,分組已經按我們的要求實現了。

  • 排序

基本實現排序

1 private void buttonSort_Click(object sender, RoutedEventArgs e)
2         {
3             ICollectionView view = GetFamilyView();
4             view.SortDescriptions.Add(new SortDescription("Age", ListSortDirection.Ascending));
5         }

有時候默認的比較器不能滿足我們排序的需求,我們會用到自定義排序

 1 class PersonAgeSort: IComparer
 2     {
 3 
 4         #region IComparer 成員
 5 
 6         public int Compare(object x, object y)
 7         {
 8             Person personx = x as Person;
 9             Person persony = y as Person;
10             if (personx.Age > persony.Age)
11             {
12                 return 1;
13             }
14             else if (personx.Age == persony.Age)
15             {
16                 return 0;
17             }
18             else
19             {
20                 return -1;
21             }
22             //return personx.Age.CompareTo(persony.Age);
23         }
24 
25         #endregion
26     }
27 
28      然后,按鈕事件改為: 
29 
30         private void buttonSort_Click(object sender, RoutedEventArgs e)
31         {
32             ListCollectionView view = GetFamilyView() as ListCollectionView;
33             view.CustomSort = new PersonAgeSort();                        
34         }

注意按鈕事件中,我們將GetFamilyView方法返回值轉型為了ListCollectionView。因為他在WPF時用來包裝IList接口並提供視圖功能的類。在WPF中還有一些ICollectionView接口的實現,但有些不提供自定義排序,所以在使用起來要注意。尤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM