DataGrid模版列簡介
DataGrid在Silverlight中是一個重要的數據控件,可以分組顯示,可以排序,自定義模版,極大的方便了我們對數據集的操作和展示。通常爲了添加模版列,我們需要將DataGrid的AutoGenerateColumns屬性設爲false
DataGrid中對於添加的列類型有三種:
DataGridTemplateColumn (自定義模板列) ----可以添加任何控件,比如Image,button 等等
DataGridTextColumn (文本列)-----只需對其進行簡單的數據綁定
DataGridCheckBoxColumn (選擇列)----只需對其進行簡單的數據綁定即可
自定義模版頭
我們知道Silverlight自帶的模版頭樣式不能夠放入CheckBox,testbox等控件,即便是DataGridCheckBoxColumn選擇列也只能在數據行中才能顯示CheckBox框但實際項目中,我們常常遇到這樣的問題,例如我們要全選某一列,那麼我們就需要在模版頭上有一個CheckBox.,這裏我們可以修改模版頭的樣式來實現。代碼如下:
<sdk:DataGridCheckBoxColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False" Width="*" Binding="{Binding isTaxed}" >
<sdk:DataGridCheckBoxColumn.HeaderStyle>
<Style TargetType="Primitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel >
<CheckBox Content="全選" Name="chkAll"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridCheckBoxColumn.HeaderStyle>
</sdk:DataGridCheckBoxColumn>
注意:要使用此樣式,需要加入一以下命名空間支持:
xmlns:Primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
效果如下:
自定義模版列
DataGrid的單元格的狀態有兩種,即編輯狀態和非編輯狀態,在實際開發中,如果一個單元格所在的列不設爲只讀的話(即可讀可寫),那麼這個單元格就存在此兩種狀態。此時則應按需分別設定不同的編輯模版。如下:
非編輯狀態模版:<sdk:DataGridTemplateColumn.CellTemplate>
編輯狀態模版: <sdk:DataGridTemplateColumn.CellEditingTemplate>
下面以一個示例來完成介紹
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="編號" IsReadOnly="True"
Binding="{Binding EmployeeID,Mode=OneWay}" /><!--該列只讀-->
<sdk:DataGridTextColumn Header="名稱"
Binding="{Binding EmployeeName,Mode=TwoWay}" />
<sdk:DataGridTextColumn Header="年齡"
Binding="{Binding EmployeeAge,Mode=TwoWay}" />
<sdk:DataGridTemplateColumn Header="性別" Width="80">
<sdk:DataGridTemplateColumn.CellTemplate><!--普通顯示模式-->
<DataTemplate>
<TextBlock Text="{Binding EmployeeSex}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate><!--編輯模式-->
<DataTemplate>
<ComboBox Width="80" ItemsSource="{Binding cbSexList,
Source={StaticResource cbSexListProvider}}”
SelectedItem="{Binding EmployeeSex,Mode=TwoWay}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridCheckBoxColumn Header="是否稅後" Binding="{BindingEmployeeMarried,Mode=TwoWay}" />
</ sdk:DataGrid.Columns>
</sdk:DataGrid>
DataGrid實現對綁定數據的增,刪,改
難點解析
一.採用集中綁定,而非單列綁定,導致頁面數據在修改後無法實時更新問題
我們知道,在使用WCF服務時,我們一般的返回值均爲一個列表,而在前臺頁面的後臺代碼中,我們知識簡單的將列表的值綁定到DataGrid中,來完成數據的顯示,但這種後果就是,我們在修改或刪除操作時,無法實時更新頁面的顯示數據,必須採用“F5”強制刷新頁面來解決,這顯然不符合要求,這裏我們提供一種方法,僅供大家參考
二.解決方法思路:
在修改某一行的數據時,我們將此行的數據捕獲,並讀入一個類中保存,當然,DataGrid還可以將數據直接保存到一個Table行中,同樣奏效,然後將數據顯示在子窗體中,並在子窗體中完成修改,這樣我們在主窗體代碼中註冊一下子窗體的Closed事件,並在該事件中重新綁定數據源(注意,子窗體的Closed事件實在父窗體中定義而非子窗體自身),這樣我們在利用子窗體完成增加或修改操作後,均可重新綁定數據源來完成頁面刷新的效果。方法中涉及到子窗體和父窗體的交互傳值問題。
修改操作:子窗體中可以如下定義
private MainPage main;其中main即爲主窗體的實例對象,當然要使此對象完成和主窗體的交互功能,還需修改子窗體的構造函數,如下:
public ChildWindow(MainPage main)
{
InitializeComponent();
this.main=main;//完成子窗體和父窗體的聯繫。
}
當然主窗體在定義子窗體實例時,得如下定義了:
ChildWindow child=new ChildWindow(this);//這樣就達到了子父窗體的交互問題了。
private void OKButton_Click(object sender, RoutedEventArgs e)
{
//其中t爲父窗體中定義的一個Table實例對象,
Service1Client sc = new Service1Client();
main.t.產品名稱 = textBoxName.Text;
main.t.產品類型 = textBoxType.Text;
main.t.衛星類型 = textBoxSaType.Text;
main.t.行業示範類型 = textBoxjobType.Text;
main.t.產品算法名稱 = textBoxAcmName.Text;
main.t.生產時間 = textBoxTime.Text;
sc.UpdateAsync(main.t);
sc.UpdateCompleted+=new EventHandler<UpdateCompletedEventArgs>(sc_UpdateCompleted);
this.DialogResult = true;
}
父窗體中還需註冊子窗體的Closed事件,來完成頁面的刷新功能。
ChildWindow Child;//子窗體的對象
public MainPage()
{
InitializeComponent();
DataBind();//綁定數據源函數
Child.Closed += new EventHandler(Child_Closed);
}
void Child_Closed(object sender, EventArgs e)
{
if (d.DialogResult == true)
{
DataBind();
}
}
至於添加和刪除操作,相對來說比較簡單,這裏就不在贅述。
DataGrid分頁、排序和分組功能實現
實現方法簡介:
若要實現分頁及排序功能,就必須使用PagedCollectionView這個類,其功能是用來表示分組,排序,篩選,和導航分頁數據集合的視圖。關於此類的詳細介紹,請參考:
分頁功能實現
當頁面進行大量數據展示時,往往需要分頁效果,Silverlight4.0和5.0都提供了DataPager控件,這樣我們很方便就可以實現DataGrid的分頁效果。
注意事項:
當我們是直接從工具箱中拖放DataPager控件而非收到編寫XAML文件時,系統默認每頁展示的個數爲10,如果我們在XAML文件中不做修改,即便在後臺定義DataPager的PageSize屬性爲4,界面顯示的行數仍然爲10,因爲XAML屬性在編譯時的優先級高。
這裏我們使用一個集合類來充當數據源,來解釋分頁功能的實現
獲得數據源
public List<EmployeeInfo> GetEmployeeList()
{
List<EmployeeInfo> employeeList = new List<EmployeeInfo>();
EmployeeInfo[] test = new EmployeeInfo[12];
test[0] = new EmployeeInfo(1, "張三", 1000,"開封" ,"Images/1.jpg",true);
test[1] = new EmployeeInfo(2, "張四", 2000, "開封","Images/3.jpg",true);
test[2] = new EmployeeInfo(3, "張五", 3000, "開封","Images/4.jpg",false);
test[3] = new EmployeeInfo(4, "張六", 4000, "開封","Images/5.jpg",true);
test[4] = new EmployeeInfo(5, "張七", 5000, "開封","Images/7.jpg",false);
test[5] = new EmployeeInfo(6, "張八", 6000, "開封","Images/8.jpg",true);
test[6] = new EmployeeInfo(7, "張九", 7000, "開封","Images/10.jpg",false);
test[7] = new EmployeeInfo(8, "張十", 8000, "開封","Images/11.jpg",true);
test[8] = new EmployeeInfo(9, "李四", 9000, "開封","Images/12.jpg",false);
test[9] = new EmployeeInfo(10, "李五", 10000, "開封","Images/13.jpg",true);
test[10]=newEmployeeInfo(11, "李五", 11000, "開封","Images/14.jpg",false);
test[10]=new EmployeeInfo(12, "李六", 12000, "開封","Images/15.jpg",true);
employeeList.AddRange(test);
return employeeList;
}
綁定數據實現分頁
public MainPage()
{
InitializeComponent();
PagedCollectionView pcv = new PagedCollectionView(GetEmployeeList());
dataPagerdemo01.Source = pcv;//設置DataPager數據源
dataGrid1.ItemsSource = pcv;//設置DataGrid數據源
}
同時,如果我們是直接從工具箱中拖放控件,請修改XAML文件中的PageSize屬性,例如<sdk:DataPager Source="{Binding}" PageSize="4" x:Name="dataPagerdemo01"………/>
最後效果如下:
排序功能實現
實現方法簡介:
主要使用了PagedCollectionView類的SortDescriptions屬性來控制視圖選項,基本思路是選擇集合中的某個屬性作爲參照,再設置排序的方式,最終這種設置會被一個SortDescription對象捕獲,若同時對多個屬性進行排序,按照添加至SortDescriptions的順序表示優先級。
排序功能實現:
pcv.SortDescriptions.Add
(new SortDescription("Salary",ListSortDirection.Descending));
pcv.SortDescriptions.Add
(new SortDescription("EmployeeID",ListSortDirection.Ascending));
dataPagerdemo01.Source = pcv;
dataGrid1.ItemsSource = pcv;
這樣,集合會根據Salary屬性進行降序排列,如果Salary屬性相同,則根據EmployeeID屬性進行升序排列。效果如下:
如果想返回默認排序,實際上及返回源數據集合項,則可使用pcv.SortDescriptions.Clear();來完成。
分組功能實現
實現方法簡介:
主要使用了GroupDescriptions這一屬性,它與上面所講的SortDescriptions很類似,其可以添加PropertyGroupDescription對象,把源集合進行分組
分組功能實現
pcv.GroupDescriptions.Add(new PropertyGroupDescription(“isTaxed”));
效果如下:
其中,分組是根據isTaxed的值來區分的,其值有Fasle和True兩項,但通常,我們顯示的分組表頭爲漢字,那麼我們可以新建一個屬性轉換類來實現此類效果。
在public partial class Mainpage:UserControl類中,加入一個轉換類:
public class BoolValueConvertrt : IValueConverter
{
public object Convert(object value, Type targetType, object parameter , System.Globalization.CultureInfo culture)
{
return (bool)value ? "稅後" : "非稅後";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
再修改分組語句如下:
pcv.GroupDescriptions.Add(new PropertyGroupDescription("isTaxed",new BoolValueConvertrt()));,最後的效果如下: