上海百维科技,上海网站建设 上海软件开发公司热线电话:021-57700304  
  首 页 产品与服务 软件定制 成功案例 思源优势 技术学院 关于我们 联系我们
 
 
思源软件学院 >>> 根目录>>.NET技术>>Silverlight >>>[Silverlight]简单实现DataGrid应用CheckBox选择行
发号施令爱情中是行不通的——蒙田(上海网站建设)

[Silverlight]简单实现DataGrid应用CheckBox选择行


Admin
2012年1月23日


以前写过几个办法实现这个功能,但终极还是选择了不持续DataGrid,所以再从头公布出来。


先显示终极成果,此中左边是错误的例子,右边才是正确的








在DataGrid中应用CheckBox选择行时典范的错误就是CheckBox没有Binding到任何属性上,如许的话当拖动迁移转变条时CheckBox.IsChecked就会乱掉,如Demo中左边那个DataGrid所示。最直观的解决办法是禁用DataGrid的迁移转变条,或者在绑定的数据上添加一个用于绑定CheckBox的bool属性。

其实只要在DataGrid.LoadingRow事务中将CheckBox的DataContext设定为别的一个Object,就不须要就义DataGrid的高效能,也不须要改变原稀有据的布局。终极的实现办法是自定义一个包含DataGrid的DataGridTemplateColumn,而不须要重写DataGrid,如许的坏处就是每次调用须要多写一局代码,若是不想如许就持续DataGrid然后把这句代码写进去。在DataGrid.Columns中参加自定义的Column,然后在代码中接洽关系DataGrid和这个Colum,就完成了:


 



 <sdk:DataGrid ItemsSource="{Binding}"

                      AutoGenerateColumns
="False"

                      Grid.Column
="1"

                      x:Name
="TestDataGrid">

            <sdk:DataGrid.Columns>

                <local:DataGridSelectColumn />

                <sdk:DataGridTextColumn Header="Name"

                                        Binding
="{Binding Name}"

                                        Width
="*" />

            </sdk:DataGrid.Columns>

        </sdk:DataGrid>


 



   TestDataGrid.EnableSelect();


 


下面是这个DataGridSelectColumn的具体实现。创建一个UserControl然后把它改成DataGridTemplateColumn,如许益处是DataTemplate和Style中的FrameworkElement都可以轻松地获取。


 



<sdk:DataGridTemplateColumn xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"

                            x:Class
="DataGridSelectSample.DataGridSelectColumn"

                            xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

                            xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"

                            xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"

                            xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"

                            mc:Ignorable
="d" 

                            d:DesignHeight
="300"

                            d:DesignWidth
="400">

    <sdk:DataGridTemplateColumn.HeaderStyle>

        <Style TargetType="ContentControl">

            <Setter Property="ContentTemplate">

                <Setter.Value>

                    <DataTemplate>

                        <CheckBox  Content="Select All"

                                   VerticalContentAlignment
="Center"

                                   VerticalAlignment
="Center"

                                   Loaded
="OnHeaderCheckBoxLoaded"/>

                    </DataTemplate>

                </Setter.Value>

            </Setter>

        </Style>

    </sdk:DataGridTemplateColumn.HeaderStyle>

    <sdk:DataGridTemplateColumn.CellTemplate>

        <DataTemplate>

            <CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay}"

                      VerticalAlignment
="Center"

                      HorizontalAlignment
="Center" />

        </DataTemplate>

    </sdk:DataGridTemplateColumn.CellTemplate>

</sdk:DataGridTemplateColumn>


 


 



public partial class DataGridSelectColumn : DataGridTemplateColumn

    {



        private DataGrid _ownerDataGrid;

        private CheckBox _headerCheckBox;

        private Dictionary<object, MarkObject> _markObjects;



        public event EventHandler SelectedItemChanged;



        public DataGridSelectColumn()

        {

            InitializeComponent();

            IsReadOnly = true;

            _markObjects = new Dictionary<object, MarkObject>();

        }



        public DataGrid OwnerDataGrid

        {

            get { return _ownerDataGrid; }

            set

            {

                _ownerDataGrid = value;

                _ownerDataGrid.LoadingRow += OnLoadingRow;

            }

        }



        public void SelecteAll()

        {

            if (_headerCheckBox != null

                _headerCheckBox.IsChecked = true;

            SetAllSelectedStates(true);

        }



        public void UnAll()

        {

            if (_headerCheckBox != null

                _headerCheckBox.IsChecked = 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).IsSelected)

                        result.Add((T)enu.Current);

                }

            }

            ClearItems();

            return result;

        }



        public void SetSelectedItems(IList items)

        {

            if (_ownerDataGrid.ItemsSource == null

                return;



            var enu = _ownerDataGrid.ItemsSource.GetEnumerator();

            while (enu.MoveNext())

            {

                GetMarkObject(enu.Current).IsSelected = items.Contains(enu.Current);

            }

        }



        private void ClearItems()

        {

            var enu = _ownerDataGrid.ItemsSource.GetEnumerator();

            List<object> list = new List<object>();

            while (enu.MoveNext())

            {

                list.Add(enu.Current);

            }

            List<object> removableObjects = new List<object>();

            foreach (var item in _markObjects)

            {

                if (list.Contains(item.Key) == false

                {

                    removableObjects.Add(item.Key);

                }

            }

            for (int i = 0; i < removableObjects.Count; i++)

            {

                _markObjects.Remove(removableObjects[i]);

            }

        }



        private void OnHeaderCheckBoxLoaded(object sender, RoutedEventArgs e)

        {

            _headerCheckBox = sender as CheckBox;

            _headerCheckBox.Loaded -= OnHeaderCheckBoxLoaded;

            _headerCheckBox.Checked += (s2, e2) => SetAllSelectedStates(true);

            _headerCheckBox.Unchecked += (s2, e2) => SetAllSelectedStates(false);

        }



        private void OnLoadingRow(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).IsSelected = value;

            }

            ClearItems();

        }



        private MarkObject GetMarkObject(Object obj)

        {

            if (_markObjects.ContainsKey(obj) == false

            {

                MarkObject markObject;

                markObject = new MarkObject();

                _markObjects.Add(obj, markObject);

                markObject.PropertyChanged += (s, e) =>

                {

                    if (e.PropertyName == "IsSelected"

                    {

                        if (SelectedItemChanged != null

                        {

                            SelectedItemChanged(this, EventArgs.Empty);

                        }

                    }

                };

            }



            return _markObjects[obj];

        }

    }


 


此中MarkObject是一个持续INotifyPropertyChanged的类,包含Selected属性,如许更改IsSelected时可以更新UI。


最后加上DataGridExtensions
是为了便利调用。


 




 


View Code

  public static class DataGridExtensions

    {

        internal static DataGridSelectColumn GetSelectColumn(this DataGrid dataGrid)

        {

            DataGridSelectColumn result = null;

            for (int i = 0; i < dataGrid.Columns.Count; i++)

            {

                result = dataGrid.Columns[i] as DataGridSelectColumn;

                if (result != null

                    break;

            }

            return result;

        }



        public static void EnableSelect(this DataGrid dataGird)

        {

            var column = GetSelectColumn(dataGird);

            column.OwnerDataGrid = dataGird;

        }



        public static void SelectAll(this DataGrid dataGrid)

        {

            DataGridSelectColumn column = GetSelectColumn(dataGrid);

            if (column == null

                throw new Exception("No Select Column");

            column.SelecteAll();

        }



        public static void UnAll(this DataGrid dataGrid)

        {

            DataGridSelectColumn column = GetSelectColumn(dataGrid);

            if (column == null

                throw new Exception("No Select Column");

            column.UnAll();

        }



        public static List<T> GetSelectedItems<T>(this DataGrid dataGrid)

        {

            DataGridSelectColumn column = GetSelectColumn(dataGrid);

            if (column == null

                throw new Exception("No Select Column");

            return column.GetSelectedItems<T>();

        }



        public static void SetSelectedItems(this DataGrid dataGrid, IList items)

        {

            DataGridSelectColumn column = GetSelectColumn(dataGrid);

            if (column == null

                throw new Exception("No Select Column");

            column.SetSelectedItems(items);

        }

    }



 


附上完全源码,迎接斧正。


/Files/dino623/DataGridSelectSample.zip


 

上海软件开发公司业务部:黄浦区重庆北路211号602室 | 上海软件开发公司技术部:松江区天云路259号| 上海软件开发公司综合部:松江区南期昌路346弄50号401室
上海软件开发 Copyright © 2005-2010 All Rights Reserved 电话:021-57616508  传真:57661889
沪ICP备05011021号