Create DataGridRowsDetails in code behind WPF - c#

i'm working on a new program that will show information about Test on some Tools in my factory.
For doing that i'm creating a DataGrid Control at run time and populate it.This part is working very well.
My problem is to add RowDetails, How can i do that in code behind?
if (datatable.Rows.Count != 0)
{
foreach (DataRow dt in datatable.Rows)
{
if (last_tool_test == "" || last_tool_test != dt[1].ToString())
{
last_tool_test = dt[1].ToString();
txt = new TextBlock();
txt.Text = dt[1].ToString() + " :";
txt.TextDecorations = TextDecorations.Underline;
txt.HorizontalAlignment = HorizontalAlignment.Center;
txt.Margin = new Thickness(0, 0, 0, 7);
data = new DataGrid();
data.Width = double.NaN;
data.Margin = new Thickness(5, 0, 5, 5);
data.HeadersVisibility = DataGridHeadersVisibility.Column;
data.CanUserAddRows = false;
data.CanUserDeleteRows = false;
data.CanUserReorderColumns = false;
data.CanUserResizeColumns = false;
data.CanUserSortColumns = false;
data.IsReadOnly = true;
data.SelectionMode = DataGridSelectionMode.Extended;
DataGridTextColumn col1 = new DataGridTextColumn();
col1.Header = "Recipe Name";
col1.Binding = new Binding("Recipe_Name");
col1.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
var style = new Style(typeof(DataGridColumnHeader));
style.Setters.Add(new Setter()
{
Property = HorizontalAlignmentProperty,
Value = HorizontalAlignment.Stretch
});
style.Setters.Add(new Setter()
{
Property = HorizontalContentAlignmentProperty,
Value = HorizontalAlignment.Center
});
style.Setters.Add(new Setter()
{
Property = FontWeightProperty,
Value = FontWeights.Bold
});
var style1 = new Style(typeof(TextBlock));
style1.Setters.Add(new Setter()
{
Property = HorizontalAlignmentProperty,
Value = HorizontalAlignment.Center
});
col1.HeaderStyle = style;
col1.ElementStyle = style1;
data.Columns.Add(col1);
DataGridTextColumn col2 = new DataGridTextColumn();
col2.Header = "Foup";
col2.Width = 100;
col2.Binding = new Binding("Foup");
col2.HeaderStyle = style;
col2.ElementStyle = style1;
data.Columns.Add(col2);
DataGridTextColumn col3 = new DataGridTextColumn();
col3.Header = "Need Reference?";
col3.Width = 110;
col3.HeaderStyle = style;
col3.ElementStyle = style1;
col3.Binding = new Binding("Reference");
data.Columns.Add(col3);
DataGridTextColumn col4 = new DataGridTextColumn();
col4.Header = "# Iteration";
col4.Width = 100;
col4.HeaderStyle = style;
col4.ElementStyle = style1;
col4.Binding = new Binding("Iteration");
data.Columns.Add(col4);
DataGridTextColumn col5 = new DataGridTextColumn();
col5.Header = "Spec";
col5.Width = 100;
col5.HeaderStyle = style;
col5.ElementStyle = style1;
data.Columns.Add(col5);
col5.Binding = new Binding("Spec");
st.Children.Add(txt);
st.Children.Add(data);
}
data.Items.Add(new Tool_Test() { Recipe_Name = dt[2].ToString(), Foup = dt[3].ToString(), Reference = dt[4].ToString(), Iteration = dt[5].ToString(), Spec = dt[6].ToString() });
}
last_tool_test = "";
}
}
edit: I think i found a solution by using resource:
<Window.Resources>
<DataTemplate x:Key="CustomTemplate">
<DataGrid x:Name="datagrid1" HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" SelectionMode="Extended" Margin="5,0,5,50" CanUserResizeColumns="False" AutoGenerateColumns="False" VerticalAlignment="Top" IsReadOnly="True" Width="750">
<DataGrid.Columns>
<DataGridTextColumn Header="Sub Test Name" Width="*" Binding="{Binding Path=Recipe_Name}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Spec" Width="*" Binding="{Binding Path=Foup}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</Window.Resources>
and in my code i added this:
data.RowDetailsTemplate = (DataTemplate)this.Resources["CustomTemplate"];
Now it's half working. I don't have experience with resource so i can't find a solution to Bind data to it. How can i do that?
Thank you for your help.

You could set the RowDetailsTemplate property to a DataTemplate that you create programmatically using the XamlReader class, e.g.:
string template = "<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x = \"http://schemas.microsoft.com/winfx/2006/xaml\"><TextBlock Text=\"some text...\"></DataTemplate>";
data.RowDetailsTemplate = XamlReader.Parse(template) as DataTemplate;

I have built something along those lines a generic User Control that you can throw any ObservableCollection of objects at it and it will build the table, but you want to define the headers column widths etc. so it doesn't just use the function names for headers and default widths.
First I created an object to hold the settings for each column:
public DataGridColumnSettings(string Header, int ColumnIndex, bool IsReadOnly = true, string Width = "100", bool ComboBoxColumn = false, bool CheckBoxColumn = false)
{
this.Header = Header;
this.ColumnIndex = ColumnIndex;
this.IsReadOnly = IsReadOnly;
this.Width = Width;
this.ComboBoxColumn = ComboBoxColumn;
this.CheckBoxColumn = CheckBoxColumn;
}
I then make a collection of these for each Model (I was using the MVVM pattern):
public static Dictionary<string, DataGridColumnSettings> ColumnSettings
{
get { return new Dictionary<string, DataGridColumnSettings>() { { "PurchaseOrder", new DataGridColumnSettings("Order Number", 0) }, { "Width", new DataGridColumnSettings("Width", 1) }, { "Length", new DataGridColumnSettings("Length", 2) }, { "NumberOfPallets", new DataGridColumnSettings("No of Pallets", 3) }, { "BoardsPerStack", new DataGridColumnSettings("No of Boards", 4) }, { "NumberOfBoards", new DataGridColumnSettings("Total Boards", 5) } }; ; }
}
The dictionary keys are the get set methods from the model for the required value in the table row (this is what the columns will be called by default)
and pass in this dictionary when creating the view object (UserControl) and store it inside the View:
v_DataTable View = new v_DataTable(Model.ColumnSettings);
now add a handler for the data grids Auto Generating Column event:
<DataGrid AutoGeneratingColumn="dataGrid_AutoGeneratingColumn" /> (xaml)
and add the handler to the code behind:
private void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
string headername = e.Column.Header.ToString();
//// Any column not in header details is a hidden column
if (this.headerDetails.ContainsKey(headername))
{
Style centerStyle = new Style { TargetType = typeof(DataGridCell) };
centerStyle.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center));
Style headerCenterStyle = new Style { TargetType = typeof(DataGridColumnHeader) };
headerCenterStyle.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
try
{
e.Column.Width = Double.Parse(this.headerDetails[headername].Width);
}
catch(Exception ex)
{
e.Column.Width = 100;
}
// You can also add bindings here if required
Binding headerTextBinding = new Binding();
headerTextBinding.Source = this.headerDetails[headername];
headerTextBinding.Path = new PropertyPath("Header");
headerTextBinding.Mode = BindingMode.TwoWay;
headerTextBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(e.Column, DataGridTextColumn.HeaderProperty, headerTextBinding);
e.Column.HeaderStyle = headerCenterStyle;
e.Column.DisplayIndex = this.headerDetails[headername].ColumnIndex; //// If you have issues with the index been out of range, change the order of the get/set functions in the model class
e.Column.CellStyle = centerStyle; //// putting the get/set for any fields that are not displayed first will also help to avoid the issue
e.Column.IsReadOnly = this.headerDetails[headername].IsReadOnly;
}
else
{
e.Column.Visibility = Visibility.Hidden;
}
}
here you can use the settings you passed in to customise the columns as you require. (Should this be in the View Model if following MVVM pattern?)

I think i found a solution by using resource:
<Window.Resources>
<DataTemplate x:Key="CustomTemplate">
<DataGrid x:Name="datagrid1" HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" SelectionMode="Extended" Margin="5,0,5,50" CanUserResizeColumns="False" AutoGenerateColumns="False" VerticalAlignment="Top" IsReadOnly="True" Width="750">
<DataGrid.Columns>
<DataGridTextColumn Header="Sub Test Name" Width="*" Binding="{Binding Path=Recipe_Name}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Spec" Width="*" Binding="{Binding Path=Foup}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
and in my code i added this:
data.RowDetailsTemplate = (DataTemplate)this.Resources["CustomTemplate"];
Now it's half working. I don't have experience with resource so i can't find a solution to Bind data to it. How can i do that?

Related

How to create a DataTrigger programatically with Binding="{Binding}"?

What's the equivelant of this DataTrigger in C# code?
<DataTrigger
Binding="{Binding}"
Value="{x:Null}">
<Setter
Property=SomeProperty
Value=SomeValue />
</DataTrigger>
I am skeptical on how to create the Binding. Is this correct?
var trigger = new DataTrigger();
trigger.Value = null;
// Is this sufficient?
trigger.Binding = new Binding();
// Code to create the setter
// ...
This would be the equivalent of your XAML:
var trigger = new DataTrigger()
{
Value = null,
Binding = new Binding(".")
};
trigger.Setters.Add(new Setter() { Property = SomeProperty, Value = SomeValue });

change Datagrid-column's/cell's width for specific rows

I currently trying to change a cell's width if that row's data has a specified state. Each row displays a MediaRow with several columns, in case of an error (MediaRow's HasError = true) some columns should be hidden and the column 'status' should be enlarged and take the space of the now-hidden-columns.
Due to the requirement to have a user-defined order of the columns, I'm creating the columns programmatically.
Note: I removed several columns (and therefore properties of MediaRow) for readability.
MediaRow:
public class MediaRow : INotifyPropertyChanged
{
private string _status = string.Empty;
private string _barcode = string.Empty;
private string _medgrp = string.Empty;
private bool _infield = false;
private bool _haserror = false;
public string MedGrp
{
get => return _medgrp;
set { _medgrp = value; NotifyPropertyChanged(); }
}
public string Barcode
{
get => return _barcode;
set { _barcode = value; NotifyPropertyChanged(); }
}
public string Status
{
get => return _status;
set
{
_status = value; NotifyPropertyChanged();
HasError = (value.ToLower().StartsWith("error")) ? true : false;
}
}
public bool InField
{
get => return _infield;
set { _infield = value; NotifyPropertyChanged(); }
}
public bool HasError
{
get => return _haserror;
set { _haserror = value; NotifyPropertyChanged(); }
}
public string Description { get; set; }
}
create Columns:
private void PopulateColumns()
{
ObservableCollection<DataGridColumn> _loccolumns = new ObservableCollection<DataGridColumn>();
DataGridTextColumn barcodecolumn = new DataGridTextColumn();
barcodecolumn.Header = ResourceManagerService.GetResourceString("EasyTerminalClient_NG", "ColumnBarcode");
barcodecolumn.Width = new DataGridLength(Settings.Instance.CheckinColumnTable["barcode"], DataGridLengthUnitType.Star);
barcodecolumn.Binding = new Binding { Path = new PropertyPath("Barcode"), Mode = BindingMode.TwoWay };
barcodecolumn.Visibility = Visibility.Hidden;
barcodecolumn.HeaderStyle = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
barcodecolumn.HeaderStyle.Setters.Add(new Setter(Control.HorizontalContentAlignmentProperty, HorizontalAlignment.Left));
barcodecolumn.HeaderStyle.Setters.Add(new Setter(Control.BackgroundProperty, System.Windows.Media.Brushes.Transparent));
barcodecolumn.HeaderStyle.Setters.Add(new Setter(Control.FontSizeProperty, new Binding { Path = new PropertyPath("headerSize"), Source = (EasyCheck.EasyTerminalClient_NG.Util.FontDetails)App.Current.FindResource("FontDetails") }));
DataGridTextColumn medgrpcolumn = new DataGridTextColumn();
medgrpcolumn.Header = ResourceManagerService.GetResourceString("EasyTerminalClient_NG", "ColumnMediaGroup");
medgrpcolumn.Width = new DataGridLength(Settings.Instance.CheckinColumnTable["mediagroup"], DataGridLengthUnitType.Star);
medgrpcolumn.Binding = new Binding { Path = new PropertyPath("MedGrp"), Mode = BindingMode.TwoWay };
medgrpcolumn.Visibility = Visibility.Hidden;
medgrpcolumn.HeaderStyle = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
medgrpcolumn.HeaderStyle.Setters.Add(new Setter(Control.HorizontalContentAlignmentProperty, HorizontalAlignment.Left));
medgrpcolumn.HeaderStyle.Setters.Add(new Setter(Control.BackgroundProperty, System.Windows.Media.Brushes.Transparent));
medgrpcolumn.HeaderStyle.Setters.Add(new Setter(Control.FontSizeProperty, new Binding { Path = new PropertyPath("headerSize"), Source = (EasyCheck.EasyTerminalClient_NG.Util.FontDetails)App.Current.FindResource("FontDetails") }));
medgrpcolumn.CellStyle = new Style(typeof(DataGridCell));
medgrpcolumn.CellStyle.Setters.Add(new Setter(DataGridCell.VisibilityProperty, new Binding() { Path = new PropertyPath("HasError"), Mode = BindingMode.OneWay, Converter = new InverseBool2VisibilityConverter() }));
DataGridTextColumn statuscolumn = new DataGridTextColumn();
statuscolumn.Header = ResourceManagerService.GetResourceString("EasyTerminalClient_NG", "ColumnState");
statuscolumn.Width = new DataGridLength(Settings.Instance.CheckinColumnTable["state"], DataGridLengthUnitType.Star);
statuscolumn.Binding = new Binding() { Path = new PropertyPath("Status"), Mode = BindingMode.OneWay, Converter = new LanguageConverter(), FallbackValue = "???" };
statuscolumn.Visibility = Visibility.Hidden;
statuscolumn.HeaderStyle = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
statuscolumn.HeaderStyle.Setters.Add(new Setter(Control.HorizontalContentAlignmentProperty, HorizontalAlignment.Left));
statuscolumn.HeaderStyle.Setters.Add(new Setter(Control.BackgroundProperty, System.Windows.Media.Brushes.Transparent));
statuscolumn.HeaderStyle.Setters.Add(new Setter(Control.FontSizeProperty, new Binding { Path = new PropertyPath("headerSize"), Source = (EasyCheck.EasyTerminalClient_NG.Util.FontDetails)App.Current.FindResource("FontDetails") }));
statuscolumn.CellStyle = new Style(typeof(DataGridCell));
//statuscolumn.CellStyle.Setters.Add(new Setter(DataGridCell.MarginProperty, "-5,-5,-5,0"));
//statuscolumn.CellStyle.Setters.Add(new Setter(DataGridCell.ActualWidthProperty, 500.0));
if (Settings.Instance.CheckinColumnSequence != null)
{
//string columnnames = "number|barcode|title|mediagroup|branch|expires|fee|state|imagestate|";
string[] columnSequence = Settings.Instance.CheckinColumnSequence;
for (int i = 0; i < columnSequence.Length; i++)
{
DataGridColumn thiscolumn = null;
switch (columnSequence[i])
{
case "barcode":
thiscolumn = barcodecolumn;
break;
case "mediagroup":
thiscolumn = medgrpcolumn;
break;
case "state":
thiscolumn = statuscolumn;
break;
}
if (thiscolumn != null)
{
thiscolumn.Visibility = Visibility.Visible;
thiscolumn.DisplayIndex = i;
_loccolumns.Add(thiscolumn);
}
}
ColumnCollection = _loccolumns;
}
}
XAML:
<UserControl.Resources>
<DataTemplate x:Key="RowDetailTemplate">
<Grid x:Name="RowDetailGrid"
Width="952"
Height="Auto"
Margin="5">
<Border HorizontalAlignment="Left"
VerticalAlignment="Top"
CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="WhiteSmoke" />
<GradientStop Offset="0.75" Color="#AAFFFFAA" />
<GradientStop Offset="1" Color="#AAFFD455" />
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Margin="10"
HorizontalAlignment="Center"
FontSize="{Binding headerSize, Source={StaticResource FontDetails}}"
FontWeight="Black"
Text="Weitere Details" />
<TextBlock Grid.Row="1"
Margin="10"
HorizontalAlignment="Left"
Text="{Binding Description}"
TextWrapping="WrapWithOverflow" />
</Grid>
</Border>
<Border Margin="0,0,0,0" CornerRadius="5">
<Border.Background>
<RadialGradientBrush Center="0.5,1" GradientOrigin="0,1" Opacity="0.3" RadiusX="0.8" RadiusY="0.8">
<GradientStop Offset="1" Color="#AACCCCCC" />
<GradientStop Offset="1" Color="WhiteSmoke" />
</RadialGradientBrush>
</Border.Background>
</Border>
</Grid>
</DataTemplate>
</UserControl.Resources>
<DataGrid x:Name="dataGrid1"
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
AlternationCount="2"
AutoGenerateColumns="False"
c:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding MediaRowCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"
MinRowHeight="26"
RowDetailsTemplate="{StaticResource RowDetailTemplate}"
RowDetailsVisibilityChanged="dataGrid1_RowDetailsVisibilityChanged"
Loaded="dataGrid1_Loaded"
Width="952"
IsReadOnly="True"
SelectionMode="Single"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserSortColumns="False"
CanUserResizeRows="False"
HorizontalScrollBarVisibility="Disabled"
AreRowDetailsFrozen="True"
HeadersVisibility="Column" VerticalScrollBarVisibility="Auto" >
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding InField}" Value="False">
<Setter Property="Background" Value="Transparent"/>
</DataTrigger>
<DataTrigger Binding="{Binding InField}" Value="True">
<Setter Property="Background" Value="#ffffffac"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<ToggleButton x:Name="RowHeaderToggleButton"
Click="ToggleButton_Click"
Cursor="Hand"/>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
</DataGrid>
In the first steps I ignored the HasError-condition and just tried to apply the desired effect to the status-cells but with no success. I'm just getting an unhandled exception. (The respective code I left as comments in the 'Create Columns' -Section.)
System.ArgumentException: '"-5,-5,-5,0" ist kein gültiger Wert für die
Eigenschaft "System.Windows.FrameworkElement.Margin" auf einem
"Setter".'
should translate to:
System.ArgumentException: '"-5,-5,-5,0" is no valid Value for the property "System.Windows.FrameworkElement.Margin" on a "Setter".'
Question:
How can I achieve the desired effect?
If MediaRow's HasError == true the MedGrp-cell should be hidden and the Status-cell should take up the MedGrp-cells's space.
I'd be happy about any suggestions, even if it is only for a fixed-value for the new status-width.
You can't set the Margin property to a string. You should set it to a Thickness:
statuscolumn.CellStyle.Setters.Add(new Setter(DataGridCell.MarginProperty, new Thickness(-5,-5,-5,0))));
This should get rid of the ArgumentException you are getting.

WPF DataGrid cell tooltip binding to a custom data

Sorry for mistakes, english is not my native language.
I'm trying to make custom tooltip for DataGrid cells. I'm trying this:
<Window.Resources>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Content="{Binding Hint}"/>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<DataGrid x:Name="dgMain" AutoGenerateColumns="True" Grid.Row="1" RowHeaderWidth ="0" BorderBrush="Aqua" BorderThickness="1"
HorizontalGridLinesBrush="Silver" VerticalGridLinesBrush="Silver" RowBackground="LightGray" AlternatingRowBackground="White">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}" >
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
This is bode behind
public class MyDataTableItem
{
public string MainText { get; set; }
public string Hint { get; set; }
public override string ToString()
{
return MainText;
}
public MyDataTableItem(string MainText, string Hint)
{
this.MainText = MainText;
this.Hint = Hint;
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// Actually, there is can be unknown number of items
string[] DocumentList = { "Doc 1", "Doc 2", "Doc 3", "Doc 4" };
MyDataTableItem[,] Revisions = new MyDataTableItem[1, 4];
Revisions[0, 0] = new MyDataTableItem("A01", "123");
Revisions[0, 1] = new MyDataTableItem("A02", "234534");
Revisions[0, 2] = new MyDataTableItem("A03", "afdf");
Revisions[0, 3] = new MyDataTableItem("A04", "ferhbr6");
dt = new DataTable();
foreach (var name in DocumentList)
{
var column = new DataColumn();
column.DataType = typeof(MyDataTableItem);
column.ColumnName = name;
column.ReadOnly = true;
column.Unique = false;
dt.Columns.Add(column);
}
var row = dt.NewRow();
int i = 0;
foreach (var name in DocumentList)
{
row[name] = Revisions[0, i];
i++;
}
dt.Rows.Add(row);
dgMain.ItemsSource = dt.DefaultView;
}
And this is don't work, tooltip is empty as expected. How can i bind tooltip to Hint property of MyDataTableItem?

Font size not applied to datagrid columnheader

I have a wpf datagrid in which I am adding all the columns and style through C#.
I have applied ColumnHeaderStyle as follows:
written setter as :
var fontSizeSetter = new Setter {Property = Control.FontSizeProperty, Value = Convert.ToDouble(font.Size)};
Style as:
var headerStyle = new Style();
headerStyle.Setters.Add(fontSetter);
headerStyle.Setters.Add(fontSizeSetter);
headerStyle.Setters.Add(fontStyleSetter);
headerStyle.Setters.Add(fontWeightSetter);
Applied it to my Datagrid's ColumnHeaderStyle as:
view.DataGrid.ColumnHeaderStyle = headerStyle;
Current problem:
now, when I set FontFamily & FontStyle it gets applied. but column Header textsize remains same. It does not get updated.
Entire Method:
private static void ConfigureFontsForDataGrid(Views.StatusMonitor view, StatusMonitorAgencyFontType font)
{
var fontfamily = new FontFamily(font.Font);
var fontSetter = new Setter { Property = Control.FontFamilyProperty, Value = fontfamily };
var fontSizeSetter = new Setter { Property = Control.FontSizeProperty, Value = Convert.ToDouble(font.Size) };
var fontStyleSetter = new Setter { Property = Control.FontStyleProperty };
var fontWeightSetter = new Setter { Property = Control.FontWeightProperty };
// Defaults
fontWeightSetter.Value = FontWeights.Regular;
fontStyleSetter.Value = FontStyles.Normal;
switch (font.Style)
{
case "Regular":
fontWeightSetter.Value = FontWeights.Regular;
fontStyleSetter.Value = FontStyles.Normal;
break;
case "Bold Italic":
fontWeightSetter.Value = FontWeights.Bold;
fontStyleSetter.Value = FontStyles.Italic;
break;
}
//Configuring data grid cell font
view.DataGrid.CellStyle.Setters.Add(fontSetter);
view.DataGrid.CellStyle.Setters.Add(fontSizeSetter);
view.DataGrid.CellStyle.Setters.Add(fontStyleSetter);
view.DataGrid.CellStyle.Setters.Add(fontWeightSetter);
//Configuring data grid column header font
view.DataGrid.ColumnHeaderStyle.Setters.Add(fontSetter);
view.DataGrid.ColumnHeaderStyle.Setters.Add(fontSizeSetter);
view.DataGrid.ColumnHeaderStyle.Setters.Add(fontStyleSetter);
view.DataGrid.ColumnHeaderStyle.Setters.Add(fontWeightSetter);
}
Use this code to resize font of Column Header in Datagrid:
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="FontSize" Value="10"/>
</Style>
Can you try below code.
var headerStyle = new Style();
Setter fontSetter = new Setter { Property = Control.FontFamilyProperty, Value = new FontFamily("Calibri") };
headerStyle.Setters.Add(fontSetter);
Setter fontSizeSetter = new Setter { Property = Control.FontSizeProperty, Value = Convert.ToDouble(20) };
headerStyle.Setters.Add(fontSizeSetter);
Setter fontStyleSetter = new Setter { Property = Control.FontStyleProperty, Value = FontStyles.Italic };
headerStyle.Setters.Add(fontStyleSetter);
Setter fontWeightSetter = new Setter { Property = Control.FontWeightProperty, Value = FontWeights.Bold };
headerStyle.Setters.Add(fontWeightSetter);
myGrid.ColumnHeaderStyle = headerStyle;
I wrote following data template in my datagrid resources. It works.
<DataTemplate DataType="{x:Type System:String}">
<TextBlock Text="{Binding}">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=FontFamily}" />
<Setter Property="FontSize" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=FontSize}" />
<Setter Property="FontStyle" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=FontStyle}"/>
<Setter Property="FontWeight" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=FontWeight}"/>
</Style>
</TextBlock.Resources>
</TextBlock>
</DataTemplate>

Construct listview with c#

Let's say I have the follwoing listview in xaml:
<ListView Name="myListView" DataContext="{Binding MyProperty}" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
<ListView.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView >
<GridViewColumn Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SomeProperty}" TextAlignment="Center"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
how can I create the same listview with C#?
this is what I have worked out:
ListView myListView = new ListView();
// set bindings
myListView.IsSynchronizedWithCurrentItem = true;
Binding b = new Binding("MyProperty")
{
Source = this
};
myListView.SetBinding(ListView.ItemsSourceProperty, b);
myListView.Resources.Add(; // dont know how to add those resource;
GridView g = new GridView();
GridViewColumn gc = new GridViewColumn();
DataTemplate dt = new DataTemplate(new TextBlock()); // I think this is wrong
g.Columns.Add(gc); // add gridview column
gc.CellTemplate = dt;
myListView.View = g;
Resource adding:
view.Resources.Add(typeof(GridViewColumnHeader),
new Style(typeof(GridViewColumnHeader))
{
Setters =
{
new Setter(GridViewColumnHeader.VisibilityProperty, Visibility.Collapsed)
}
}
);
DataTemplate creating:
var template = new DataTemplate();
var textBlock = new FrameworkElementFactory(typeof(TextBlock));
textBlock.SetBinding(TextBlock.TextProperty, new Binding("SomeProperty"));
textBlock.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Center);
template.VisualTree = textBlock;

Categories

Resources