I am using DataGrid
to show storagehouse occupancy (Occupied-Show Image With a box, Not Occupied-Show Empty Image).
In DataGrid I am using DataGridTemplateColumn
to override the Images.
My Main Form XAML Code:
<xctk:BusyIndicator Name="ctrlBusy" IsBusy="False" BusyContent="Generating Maps..." >
<Grid>
<StackPanel>
<Button Name="btnClick" Grid.Row="0" Click="Button_Click_1" Height="44" VerticalAlignment="Top"
HorizontalAlignment="Left" Width="114" Panel.ZIndex="4" Margin="6,3,0,0">Click</Button>
<StackPanel Orientation="Vertical" Grid.Row="1">
<TextBlock Background="SkyBlue" Height="50">
</TextBlock>
<DataGrid GridLinesVisibility="None" Background="SkyBlue"
BorderBrush="Transparent" IsReadOnly="True" ItemsSource="{Binding}"
AutoGenerateColumns="True" AutoGeneratingColumn="dgvMap_AutoGeneratingColumn"
CanUserAddRows="False" CanUserSortColumns="true" CanUserDeleteRows="False"
HeadersVisibility="Row" Name="dgvMap" SelectionMode="Single"
Panel.ZIndex="0" Margin="0,0,0,0" VirtualizingStackPanel.VirtualizationMode="Standard">
<!--for removing the blue color bkground default for row selection-->
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
</DataGrid.Resources>
</DataGrid>
<TextBlock Background="SkyBlue" Height="50">
</TextBlock>
</StackPanel>
</StackPanel>
</Grid>
</xctk:BusyIndicator>
Datatemplate for DataGrid:
<DataTemplate x:Key="MyDataTemplate" DataType="DataRowView">
<Grid Background="Transparent">
<Image Tag="{Binding}" Name="Layer0" Margin="0,0,0,0" Panel.ZIndex="1"
Width="50" Height="50" ToolTipService.HasDropShadow="True" ToolTipService.ShowDuration="20000" ToolTipService.InitialShowDelay="200" >
<Image.ToolTip>
<StackPanel>
<Label FontWeight="Bold" Background="Blue" Foreground="White" Content="{Binding}" />
<TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200">
This coil is located in this location. Yard Name is FG. Zone is Dispatch Area.
</TextBlock>
<Line Stroke="Black" StrokeThickness="1" X2="200" />
<StackPanel Orientation="Horizontal">
<Label FontWeight="Bold">Report to admin in case of coil location mismatch</Label>
</StackPanel>
</StackPanel>
</Image.ToolTip>
<Image.Resources>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{Binding Converter={StaticResource IntToImageConverter}, ConverterParameter = Layer0}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Hover image -->
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Source" Value="C:\Users\Images\Coil3.png"/>
<!--<Setter Property="Source" Value="{Binding Converter={StaticResource HoverImage}}"/>-->
</Trigger>
</Style.Triggers>
</Style>
</Image.Resources>
</Image>
</Grid>
</DataTemplate>
Main Form Code-Behind:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
btnClick.Content = "Data Loaded";
Stopwatch sw = new Stopwatch();
DataTable dt = dbLayer.tblSaddleSelectAll();
sw.Start();
dgvMap.ItemsSource = dt.DefaultView;
sw.Stop();
btnClick.Content = sw.ElapsedMilliseconds.ToString();
}
private void dgvMap_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName == "row")
{
e.Column.Visibility = System.Windows.Visibility.Hidden;
}
var column = new DataRowColumn(e.PropertyName);
column.Header = e.Column.Header;
column.CellTemplate = (DataTemplate)Resources["MyDataTemplate"];
e.Column = column;
}
ValueConverter for DataGrid:
public class BoolToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ImageSource result = null;
var intValue = value.ToString();
switch (parameter.ToString())
{
case "Layer1":
if (intValue.ToUpper().Contains("EMPTY"))
{
result = null;
}
else
{
result = new BitmapImage(new Uri(@"C:\Users\Images\Box3.png"));
}
return result;
default:
if (intValue.ToUpper().Contains("EMPTY"))
{
//result = null;
result = new BitmapImage(new Uri(@"C:\Users\Images\Box1.png"));
}
else
{
result = new BitmapImage(new Uri(@"C:\Users\Images\Box2.png"));
}
return result;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Custom DatagridTemplateColumn:
public class DataRowColumn : DataGridTemplateColumn
{
public DataRowColumn(string column) { ColumnName = column; }
public string ColumnName { get; private set; }
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
var row = (DataRowView)dataItem;
var item = row[ColumnName];
cell.DataContext = item;
var element = base.GenerateElement(cell, item);
return element;
}
}
The Data from Database will be like this:
I will be loading maximum of 250 columns, 20 rows from database.
My questions:
- Is
datagrid
is best way to show map kind of layouts for the data given range? I need to show presence and absence with sometooltip
descriptions. - The stopwatch i kept for checking time taken to load DataGrid. It is showing value less than 250ms. But in reality it is taking too much take show and for 4-6 second the UI gets hanged. Why is hanging? How to overcome it? How can i show BusyIndicator till DataGrid is fully created?
- Is attaching
DataTable
'sDefaultView
toDataGrid
is better way to do in performance in wise?? - Is there anything(properties) I missed in
DataGrid
to improve the performance.