[Silverlight]实现DataGrid使用CheckBox选择行(2)
时间:2011-02-25 来源:dino623
先写一个XAML,主意在属性中将生成的操作改为“嵌入的资源”
Resources.xaml <Style x:Key="SelectColumnHeaderStyle"TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<local:MyCheckBox Content="Select All"
VerticalContentAlignment="Center"
VerticalAlignment="Center" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="SelectColumnCellTemplate">
<CheckBox IsChecked="{Binding Selected,Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</DataTemplate
其中的MyCheckBox:
MyCheckBox public class MyCheckBox : CheckBox{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
DataGrid dataGrid = this.GetParent<DataGrid>();
if (dataGrid == null)
return;
dataGrid.SetSelectCheckBox(this);
}
为了调用方便,写几个扩展方法
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;
}
internal static void SetSelectCheckBox(this DataGrid dataGrid, CheckBox checkBox)
{
DataGridSelectColumn column = GetSelectColumn(dataGrid);
column.EnableSelect(dataGrid, checkBox);
}
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 UnselectAll(this DataGrid dataGrid)
{
DataGridSelectColumn column = GetSelectColumn(dataGrid);
if (column == null)
throw new Exception("No Select Column");
column.UnselectAll();
}
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>();
最后是SelectColumn
DataGridSelectColumn public class DataGridSelectColumn : DataGridTemplateColumn{
private const string SelectColumnHeaderStyle = "SelectColumnHeaderStyle";
private const string SelectColumnCellTemplate = "SelectColumnCellTemplate";
private const string TemplateXamlPath = "DataGridTestLib.Assets.Resources.xaml";
private static ResourceDictionary _resourceDictionary;
private DataGrid _dataGrid;
private CheckBox _headerCheckBox;
private Dictionary<object, MarkObject> _markObjects;
public DataGridSelectColumn()
{
HeaderStyle = GetResourceDictionary()[SelectColumnHeaderStyle] as Style;
CellTemplate = GetResourceDictionary()[SelectColumnCellTemplate] as DataTemplate;
IsReadOnly = true;
}
private ResourceDictionary GetResourceDictionary()
{
if (_resourceDictionary == null)
{
Stream stream = this.GetType().Assembly.GetManifestResourceStream(TemplateXamlPath);
using (StreamReader reader = new StreamReader(stream))
{
string resourceXaml = reader.ReadToEnd();
_resourceDictionary = XamlReader.Load(resourceXaml) as ResourceDictionary;
}
}
return _resourceDictionary;
}
internal void EnableSelect(DataGrid dataGrid, CheckBox checkBox)
{
_dataGrid = dataGrid;
_headerCheckBox = checkBox;
_markObjects = new Dictionary<object, MarkObject>();
_headerCheckBox.Checked += (sender, e) => SetAllSelectedStates(true);
_headerCheckBox.Unchecked += (sender, e) => SetAllSelectedStates(false);
_dataGrid.LoadingRow += OnLoadingRow;
}
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 (_dataGrid.ItemsSource == null)
return;
var enu = _dataGrid.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()
{
if (_headerCheckBox != null)
_headerCheckBox.IsChecked = true;
SetAllSelectedStates(true);
}
public void UnselectAll()
{
if (_headerCheckBox != null)
_headerCheckBox.IsChecked = false;
SetAllSelectedStates(false);
}
public List<T> GetSelectedItems<T>()
{
List<T> result = new List<T>();
if (_dataGrid.ItemsSource != null)
{
var enu = _dataGrid.ItemsSource.GetEnumerator();
while (enu.MoveNext())
{
if (GetMarkObject(enu.Current).Selected)
result.Add((T)enu.Current);
}
}
return result;
}
其中GetResourceDictionary方法就是读取XAML的函数。
最终的调用方式如下:
<sdk:DataGrid ItemsSource="{Binding}"AutoGenerateColumns="False"
Grid.Column="2"
x:Name="TestDataGrid2">
<sdk:DataGrid.Columns>
<my:DataGridSelectColumn />
<sdk:DataGridTextColumn Header="Name"
Binding="{Binding Name}"
Width="*" />
<sdk:DataGridTextColumn Header="GUID"
Binding="{Binding GUID}"
Width="*" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
相关阅读 更多 +