今天在MSDN論壇回答問題的時候,看到有人在問說要怎麼在執行時期動態的顯示或是隱藏欄位,雖然我不清楚他確切的需求,不過基於好奇心和好勝心作怪,我還是寫出了下面這個範例~
有興趣的朋友可以參考看看,如果有想到什麼情境下或是這樣的功能很適合用在什麼地方的話,也歡迎留個言交流一下喔!!
今天在MSDN論壇回答問題的時候,看到有人在問說要怎麼在執行時期動態的顯示或是隱藏欄位,雖然我不清楚他確切的需求,不過基於好奇心和好勝心作怪,我還是寫出了下面這個範例~
有興趣的朋友可以參考看看,如果有想到什麼情境下或是這樣的功能很適合用在什麼地方的話,也歡迎留個言交流一下喔!!
先來看看Xaml原始碼:
<UserControl
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"
xmlns:theme="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.ExpressionDark"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SL_DynamicDataGridColumns.MainPage"
mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="800">
<theme:ExpressionDarkTheme Background="{x:Null}" Foreground="#FF646464">
<Border BorderThickness="2" CornerRadius="10" Margin="10" Background="White" BorderBrush="#FF646464">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Silverlight動態顯示DataGrid欄位範例"
VerticalAlignment="Center" FontSize="26.667" FontWeight="Bold" />
<Rectangle Fill="#FF646464" Height="2" Margin="10,0" VerticalAlignment="Bottom" />
<Grid Margin="10" Grid.Row="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="0.635*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="myListBox" Margin="10" FontSize="13.333" SelectionMode="Multiple"/>
<sdk:DataGrid x:Name="myDataGrid" Grid.Column="1" Margin="10" AutoGenerateColumns="True"
DataContext="{Binding Source={StaticResource SampleDataSource}}"
ItemsSource="{Binding Collection}" FontSize="13.333"
AutoGeneratingColumn="myDataGrid_AutoGeneratingColumn">
<!--
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Property1}" Header="Property1"/>
<sdk:DataGridCheckBoxColumn Binding="{Binding Property2}" Header="Property2"/>
<sdk:DataGridTextColumn Binding="{Binding Property3}" Header="Property3"/>
<sdk:DataGridTextColumn Binding="{Binding Property4}" Header="Property4"/>
<sdk:DataGridTextColumn Binding="{Binding Property5}" Header="Property5"/>
<sdk:DataGridTextColumn Binding="{Binding Property6}" Header="Property6"/>
</sdk:DataGrid.Columns>
-->
</sdk:DataGrid>
</Grid>
<Button x:Name="myButton" Content="設定顯示欄位" HorizontalAlignment="Center" Grid.Row="3"
VerticalAlignment="Center" Margin="0,5" Padding="10,5" FontSize="13.333" Click="myButton_Click" />
</Grid>
</Border>
</theme:ExpressionDarkTheme>
</UserControl>
Xaml的部份其實沒什麼特別的地方,除了我在DataGrid上加了一個AutoGeneratingColumn的EventHandler,用來在自動產生欄位的時候,將用來做DataBinding的PropertyName記錄下來。另外,SampleData的部份是透過Expression Blend自動產生的。
再來看看Code-Behind的部份:
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
namespace SL_DynamicDataGridColumns
{
public partial class MainPage : UserControl
{
private ObservableCollection<string> _columns = new ObservableCollection<string>();
public MainPage()
{
InitializeComponent();
this.myListBox.ItemsSource = _columns;
//如果DataGrid的欄位不是自動產生的(AutoGenerateColumns=False),就可以在Loaded事件裡面抓取欄位。但如果是由DataGrid自動產生欄位(AutoGenerateColumns=True),在Loaded中就會抓不到欄位喔!!
//this.Loaded += new RoutedEventHandler( MainPage_Loaded );
}
private void MainPage_Loaded( object sender , RoutedEventArgs e )
{
foreach( DataGridColumn dataGridColumn in myDataGrid.Columns )
{
if( !_columns.Contains( dataGridColumn.Header.ToString() ) )
{
_columns.Add( dataGridColumn.Header.ToString() );
}
}
this.myListBox.SelectAll();
}
private void myButton_Click( object sender , RoutedEventArgs e )
{
for( int i = 0 ; i < _columns.Count ; i++ )
{
myDataGrid.Columns[ i ].Visibility = Visibility.Collapsed;
if( ( myListBox.ItemContainerGenerator.ContainerFromIndex( i ) as ListBoxItem ).IsSelected == true )
{
myDataGrid.Columns[ i ].Visibility = Visibility.Visible;
}
}
}
private void myDataGrid_AutoGeneratingColumn( object sender , DataGridAutoGeneratingColumnEventArgs e )
{
if( !_columns.Contains( e.PropertyName ) )
{
_columns.Add( e.PropertyName );
}
myListBox.SelectAll();
}
}
}
其實Code-Behind的部份,要完成這樣的功能的方式就有兩種可以選了,得視DataGrid的欄位是否為自動產生的來決定。範例中使用的DataGrid欄位為自動產生,沒辦法在MainWindow的Loaded事件中取得,所以得透過DataGrid的AutoGeneratingColumn事件來幫忙完成取得欄位的動作。
其他的部份就真的都很簡單啦,只要操作DataGridColumn的Visibility屬性,就可以做到顯示/隱藏的切換啦!!
以上~
最後附上專案原始碼,歡迎自行取用: