继续之前的话题。这次的方法仍然和上一次大同小异,只不过改变创建模版列的方法,同时也不在关注那个CheckBox。具体方法就是创建一个UserControl,让它帮我们完成获取DataTemplate和Style,其实这是一种很偷懒的方法,写起来好像也不怎么漂亮。看看下面这段XAML

 

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
             x:Class
="DataGridTestLib.DataGridSelectColumnHelper"
             xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local
="clr-namespace:DataGridTestLib">
    
<UserControl.Resources>
        
<local:MarkObject x:Key="MarkObject" />
        
<Style TargetType="sdk:DataGridColumnHeader"
               x:Name
="HeaderStyle">
            
<Setter Property="ContentTemplate">
                
<Setter.Value>
                    
<DataTemplate>
                        
<CheckBox IsChecked="{Binding Selected,Mode=TwoWay,Source={StaticResource MarkObject}}"
                                  Content
="Select All"
                                  VerticalContentAlignment
="Center"
                                  VerticalAlignment
="Center" />
                    
</DataTemplate>
                
</Setter.Value>
            
</Setter>
        
</Style>

        
<DataTemplate x:Name="CellTemplate">
            
<CheckBox IsChecked="{Binding Selected,Mode=TwoWay}"
                      VerticalAlignment
="Center"
                      HorizontalAlignment
="Center" />
        
</DataTemplate>

    
</UserControl.Resources>
</UserControl>

 

MarkObject是一个实现INotifyPropertyChanged并且有Selected的类,在这段XAML中,MarkObject的Selected与HeaderStyle中的CheckBox.IsChecked双向绑定,我们只需要操作这个MarkObject的Selected属性就可以控制DataGrid的全选功能。如果看过UserControl中自动生成的InitializeComponent()方法会发现Resource中有Name的DependancyObject都已经成为这个UserControl的internal属性,但注意MarkObject不是DependancyObject,所以要通过这段代码获取这个MarkObject

 this.MarkObject = this.Resources["MarkObject"as MarkObject;
 
 
最后只要和上次一样创建一个DataGridColumn,通过它操作全选功能就可以了。
DataGridSelectColumn2
public class DataGridSelectColumn2 : DataGridTemplateColumn
    {
        
private Dictionary<object, MarkObject> _markObjects;
        
private MarkObject _markObject;
        
private DataGrid _ownerDataGrid;
        
public DataGridSelectColumn2()
        {
            IsReadOnly 
= true;
            _markObjects 
= new Dictionary<object, MarkObject>();
            DataGridSelectColumnHelper helper 
= new DataGridSelectColumnHelper();
            
this.HeaderStyle = helper.HeaderStyle;
            
this.CellTemplate = helper.CellTemplate;
            _markObject 
= helper.MarkObject;
            _markObject.PropertyChanged 
+= (sender, e) =>
            {
                
if (_markObject.Selected)
                    SelecteAll();
                
else
                    UnselectAll();
            };
        }

        
public DataGrid OwnerDataGrid
        {
            
get
            {
                
return _ownerDataGrid;
            }
            
set
            {
                _ownerDataGrid 
= value;
                _ownerDataGrid.LoadingRow 
+= OnDataGridLoadingRow;
            }
        }

        
private void OnDataGridLoadingRow(object sender, DataGridRowEventArgs e)
        {
            
object dataContext = e.Row.DataContext;
            FrameworkElement element 
= this.GetCellContent(e.Row);
            element.DataContext 
= GetMarkObject(dataContext);
        }

        
private void SetAllSelectedStates(bool value)
        {
            
if (OwnerDataGrid.ItemsSource == null)
                
return;

            var enu 
= OwnerDataGrid.ItemsSource.GetEnumerator();
            
while (enu.MoveNext())
            {
                GetMarkObject(enu.Current).Selected 
= value;
            }
        }

        
private MarkObject GetMarkObject(Object obj)
        {
            
if (_markObjects.ContainsKey(obj) == false)
            {
                MarkObject markObject;
                markObject 
= new MarkObject();
                _markObjects.Add(obj, markObject);
            }

            
return _markObjects[obj];
        }

        
public void SelecteAll()
        {
            _markObject.Selected 
= true;
            SetAllSelectedStates(
true);
        }

        
public void UnselectAll()
        {
            _markObject.Selected 
= false;
            SetAllSelectedStates(
false);
        }

        
public List<T> GetSelectedItems<T>()
        {
            List
<T> result = new List<T>();
            
if (OwnerDataGrid.ItemsSource != null)
            {
                var enu 
= OwnerDataGrid.ItemsSource.GetEnumerator();
                
while (enu.MoveNext())
                {
                    
if (GetMarkObject(enu.Current).Selected)
                        result.Add((T)enu.Current);
                }
            }
            
return result;
        }

    }
 
记得IsReadOnly = true。
 

 

作者: dino623 发表于 2011-03-02 11:16 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架