пятница, 27 августа 2010 г.

Формат колонок в DataGrid в Silverlight 4.

Следующая задача, которую мы рассмотрим – это задание форматы данных в колонках DataGrid. Наиболее простые и часто используемые параметры – это, пожалуй, задание выравнивания текста, а также форматирование денежных данных.

Такие сценарии кажутся просто очевидными, однако в Silverlight не поддерживаются. Точнее они поддерживаются, но каким-то странным и не очевидным способом.

Предположим, что у нас есть следующее описание грида:

<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=someDomainDataSource, Path=Data}" Name="someDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" ColumnWidth="Auto" IsReadOnly="True" SelectionMode="Single" SizeChanged="someDataGrid_SizeChanged">
                         <sdk:DataGrid.Columns>
                             <sdk:DataGridTextColumn x:Name=" centeredColumn " Binding="{Binding Path= SomeField1}" Header=" Some field" MinWidth="10"/>
                             <sdk:DataGridTextColumn x:Name=" currencyColumn " Binding="{Binding Path=Long Currency}" Header=" Currency Column" MinWidth="20" />
                        


</sdk:DataGrid.Columns>
                         <i:Interaction.Behaviors>
 
                             <behaviors:DataGridDoubleClickBehavior DoubleClick="someDataGrid_DoubleClick"/>
 
                         </i:Interaction.Behaviors>
                     </sdk:DataGrid>


 


Нам нужно выровнять содержимое колонки centeredColumn по центру, выровнять содержимое колонки currencyColumn по правому краю и задать для нее денежный формат.



Оказывается, что DataGridTextColumn не поддерживает никакого параметра, отвечающего за выравнивание текста (ну почему? Это же так очевидно)!



К счастью решение есть и оно достаточно простое.



Нужно воспользоваться DataGridTemplateColumn вместо DataGridTextColumn и в ней задать нужные параметры.



<sdk:DataGridTemplateColumn x:Name="centeredColumn" MinWidth="10" Header="Some field">

<sdk:DataGridTemplateColumn.CellTemplate>


<DataTemplate>


<TextBlock Text="{Binding Path=SomeField1}" HorizontalAlignment="Center" />


</DataTemplate>


</sdk:DataGridTemplateColumn.CellTemplate>


</sdk:DataGridTemplateColumn>



Правда теперь отвалится сортировка, так что нужно добавить параметр SortMemberPath…



<sdk:DataGridTemplateColumn x:Name="centeredColumn" MinWidth="10" Header="Some field" SortMemberPath="SomeField1">


<sdk:DataGridTemplateColumn.CellTemplate>


<DataTemplate>


<TextBlock Text="{Binding Path=SomeField1}" HorizontalAlignment="Center" />


</DataTemplate>


</sdk:DataGridTemplateColumn.CellTemplate>


</sdk:DataGridTemplateColumn>



Со второй колонкой все также несложно.



Сначала выравняем ее по правому краю:



<sdk:DataGridTemplateColumn x:Name="currencyColumn" MinWidth="10" Header="Currency Column" SortMemberPath="Currency">

<sdk:DataGridTemplateColumn.CellTemplate>


<DataTemplate>


<TextBlock Text="{Binding Path=Currency}" HorizontalAlignment="Right" />


</DataTemplate>


</sdk:DataGridTemplateColumn.CellTemplate>


</sdk:DataGridTemplateColumn>



Форматирование в виде денежных единиц можно легко сделать при помощи конвертера, напишем такой конвертер:



using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Data;
 

namespace MyApplication

{
     public class CurrencyConverter : IValueConverter
     {
         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
         {
             return string.Format("{0:C}", value);
         }
 
         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
         {
             if (value == null)
                 return null;
 
             return string.IsNullOrEmpty(value.ToString()) ? null : value.ToString();
         }
     }

}


Его пространство имен нужно подключить к странице в гридом и использовать:



<navigation:Page x:Class="MyApplication.Views.Somes"

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"


xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"


d:DesignWidth="640" d:DesignHeight="480"


Style="{StaticResource PageStyle}"


xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"


xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"


xmlns:converter="clr-namespace:MyApplication"


>



<navigation:Page.Resources>



        <converter:CurrencyConverter x:Key="CurrencyConverter" />
     </navigation:Page.Resources>

                         <sdk:DataGrid.Columns>


 


<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=someDomainDataSource, Path=Data}" Name="someDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" ColumnWidth="Auto" IsReadOnly="True" SelectionMode="Single" SizeChanged="someDataGrid_SizeChanged">
                         <sdk:DataGrid.Columns>


 


<sdk:DataGridTemplateColumn x:Name="centeredColumn" MinWidth="10" Header="Some field" SortMemberPath="SomeField1">

<sdk:DataGridTemplateColumn.CellTemplate>


<DataTemplate>


<TextBlock Text="{Binding Path=SomeField1}" HorizontalAlignment="Center" />


</DataTemplate>


</sdk:DataGridTemplateColumn.CellTemplate>


</sdk:DataGridTemplateColumn>


s                            <sdk:DataGridTemplateColumn x:Name="currencyColumn" MinWidth="10" Header="Currency Column" SortMemberPath="Currency">


<sdk:DataGridTemplateColumn.CellTemplate>


<DataTemplate>


<TextBlock Text="{Binding Path=Currency, Converter={StaticResource CurrencyConverter}}" HorizontalAlignment="Right" />

</DataTemplate>


</sdk:DataGridTemplateColumn.CellTemplate>


</sdk:DataGridTemplateColumn>


</sdk:DataGrid.Columns>


<i:Interaction.Behaviors>


<behaviors:DataGridDoubleClickBehavior DoubleClick="someDataGrid_DoubleClick"/>


</i:Interaction.Behaviors>


</sdk:DataGrid>



Исходный код страницы с гридом.



<navigation:Page x:Class="MyApplication.Views.Somes" 
            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"
            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
            d:DesignWidth="640" d:DesignHeight="480"
            Style="{StaticResource PageStyle}"
                  xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
                  xmlns:my="clr-namespace:MyApplication.Web.Services"
                  xmlns:my1="clr-namespace:MyApplication.BLL"
                  xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
                  xmlns:my2="clr-namespace:MyApplication.Controls"

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

xmlns:behaviors="clr-namespace:MyApplication.Helpers;assembly=MyApplication"

xmlns:converter="clr-namespace:MyApplication"

>
     <navigation:Page.Resources>
         <converter:VisibilityConverter x:Key="VisibilityConverter" />
         <converter:CurrencyConverter x:Key="CurrencyConverter" />
     </navigation:Page.Resources>
     <Grid x:Name="LayoutRoot">
         <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}" >
 
             <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
 
                 <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
                            Text="{Binding Path=ApplicationStrings.SomesPageTitle, Source={StaticResource ResourceWrapper}}"/>
                                
                 <riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my1:Some, CreateList=true}" Height="0" LoadedData="someDomainDataSource_LoadedData" Name="someDomainDataSource" QueryName="GetSomesQuery" Width="0" >
                     <riaControls:DomainDataSource.DomainContext>
                         <my:MyApplicationDomainContext />
                     </riaControls:DomainDataSource.DomainContext>
                     <riaControls:DomainDataSource.SortDescriptors>
                         <riaControls:SortDescriptor PropertyPath="ID" Direction="Ascending"/>
                     </riaControls:DomainDataSource.SortDescriptors>
                     <riaControls:DomainDataSource.QueryParameters>
                         <riaControls:Parameter ParameterName="projectId" Value="{Binding ElementName=projectComboBox, Path=SelectedItem.ID}" />


                    </riaControls:DomainDataSource.QueryParameters>
 
                 </riaControls:DomainDataSource>
                 <my2:BusyIndicator x:Name="busyIndicator1" IsBusy="{Binding ElementName=someDomainDataSource, Path=DomainContext.IsLoading}" BusyContent="Loading..." >
 
                     <sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=someDomainDataSource, Path=Data}" Name="someDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" ColumnWidth="Auto" IsReadOnly="True" SelectionMode="Single" SizeChanged="someDataGrid_SizeChanged">
                         <sdk:DataGrid.Columns>


 


                            <sdk:DataGridTemplateColumn x:Name="centeredColumn" MinWidth="10" Header="Some field" SortMemberPath="SomeField1">
                                 <sdk:DataGridTemplateColumn.CellTemplate>
                                     <DataTemplate>
                                         <TextBlock Text="{Binding Path=SomeField1}" HorizontalAlignment="Center" />
                                     </DataTemplate>
                                 </sdk:DataGridTemplateColumn.CellTemplate>
                                 </sdk:DataGridTemplateColumn>



s                            <sdk:DataGridTemplateColumn x:Name="currencyColumn" MinWidth="10" Header="Currency Column" SortMemberPath="Currency">
                                 <sdk:DataGridTemplateColumn.CellTemplate>
                                     <DataTemplate>
                                         <TextBlock Text="{Binding Path=Currency, Converter={StaticResource CurrencyConverter}}" HorizontalAlignment="Right" />
                                     </DataTemplate>
                                 </sdk:DataGridTemplateColumn.CellTemplate>
                             </sdk:DataGridTemplateColumn>




                         </sdk:DataGrid.Columns>
                         <i:Interaction.Behaviors>
 
                             <behaviors:DataGridDoubleClickBehavior DoubleClick="someDataGrid_DoubleClick"/>
 
                         </i:Interaction.Behaviors>
                     </sdk:DataGrid>
                 </my2:BusyIndicator>
                 <sdk:DataPager x:Name="somePager" PageSize="30" Source="{Binding ElementName=someDomainDataSource, Path=Data}">
                 </sdk:DataPager>
                 <riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my1:Project, CreateList=true}" Height="0" LoadedData="projectDomainDataSource_LoadedData" Name="projectDomainDataSource" QueryName="GetProjectsQuery" Width="0" >
                     <riaControls:DomainDataSource.DomainContext>
                         <my:MyApplicationDomainContext />
                     </riaControls:DomainDataSource.DomainContext>
                 </riaControls:DomainDataSource>
 


             </StackPanel>
         </ScrollViewer>
     </Grid>

</navigation:Page>

Комментариев нет:

Отправить комментарий