I have a dinamic datagrid with dinamic number of columns.
Add one column code in my cycle:
CValueConverter valueConverter = new CValueConverter()
{
Field = fieldDg
};
Style textStyle = new Style(typeof(TextBlock));
textStyle.Setters.Add(new Setter(TextBlock.TextTrimmingProperty, TextTrimming.CharacterEllipsis));
textStyle.Setters.Add(
new Setter(
ToolTipService.ToolTipProperty,
new Binding
{
Path = new PropertyPath("[" + cmnIndex.ToString() + "]"),
Converter = valueConverter
}));
this.FormListDg.Columns.Add(new DataGridTextColumn()
{
Header = fieldDg.Name,
HeaderStyle = this.GetHeaderStyle(fieldDg.Color),
CellStyle = this.GetCellStyle(fieldDg.Color),
CanUserSort = true,
MaxWidth = 300,
Binding = new Binding
{
Path = new PropertyPath("[" + cmnIndex.ToString() + "]"),
Converter = valueConverter
},
ElementStyle = textStyle
});
cmnIndex++;
The result of this datagrid cell tooltip is:
When I change the style setter value to constant, everything is works fine:
textStyle.Setters.Add(
new Setter(
ToolTipService.ToolTipProperty,
"VALAMI"));
How can I use binding in style setter value?
The Value of the Setter should to be set to a (data-bound) Tooltip and not Binding:
ToolTip tt = new ToolTip();
tt.SetBinding(ContentControl.ContentProperty, new Binding
{
Path = new PropertyPath("[" + cmnIndex.ToString() + "]"),
Converter = valueConverter
});
textStyle.Setters.Add(
new Setter(
ToolTipService.ToolTipProperty,
tt));
Related
I'm trying to hide a dynamic combobox what is set from FrameworkElementFactory.
If i try Combobox as parameter then i get the error 'ComboBox' is a type, which is not valid in the given context and if i try fElement as parameter then it gives the error "cannot convert from 'System.Windows.FrameworkElementFactory' to 'System.Windows.DependencyObject'" I need the solution in C# not in xaml or ASP.net.
FrameworkElementFactory fElement = new FrameworkElementFactory(typeof(ComboBox));
fElement.SetValue(ComboBox.WidthProperty, 125D);
fElement.SetValue(ComboBox.ItemsSourceProperty, choices);
fElement.SetValue(ComboBox.DisplayMemberPathProperty, "Value");
fElement.SetValue(ComboBox.SelectedValuePathProperty, "Value");
fElement.SetValue(ComboBox.NameProperty, "CONAAM" + rowOnderdeel.OnderdeelID);
//fElement.SetValue(ComboBox.NameProperty, Onderdeelnaam);
fElement.AddHandler(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(cbCursistOnderdeelResultaat));
fElement.SetBinding(ComboBox.TextProperty, bind);
Interaction.GetBehaviors(ComboBox).Add(new HideComboxBehavior());
Solutions was to use System.Windows.Style and use setter to trigger the visibility of the combobox.
FrameworkElementFactory fElement = new FrameworkElementFactory(typeof(ComboBox));
fElement.SetValue(ComboBox.WidthProperty, 125D);
fElement.SetValue(ComboBox.ItemsSourceProperty, Resultaten);
fElement.SetValue(ComboBox.DisplayMemberPathProperty, "Value");
fElement.SetValue(ComboBox.SelectedValuePathProperty, "Key");
fElement.SetValue(ComboBox.SelectedValueProperty, new Binding(column.ColumnName));
Style cbStyle = new Style(typeof(ComboBox));
Setter cbSetter = new Setter(ComboBox.VisibilityProperty, Visibility.Visible);
cbStyle.Setters.Add(cbSetter);
DataTrigger cbDataTrigger = new DataTrigger();
Binding cbBinding = new Binding(column.ColumnName);
cbDataTrigger.Value = 0;
Setter cbDataSetter = new Setter(ComboBox.VisibilityProperty, Visibility.Hidden);
cbDataTrigger.Setters.Add(cbDataSetter);
cbDataTrigger.Binding = cbBinding;
cbStyle.Triggers.Add(cbDataTrigger);
fElement.SetValue(ComboBox.StyleProperty, cbStyle);
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = fElement;
gvc.CellTemplate = dataTemplate;
I'm writing a WPF application which makes use of the DataGrid control. I'm using the MaterialDesign theme to style the application and this gives a nice look and feel.
However for complex reasons I wont go into here I'm required to add the columns into the dataGrid programmatically. For some of the columns I'm also styling the columns to highlight pass / fail in red. When I do this I loose 'some of the styling' provided by material design for that columns. Namely the Horizontal and Vertical alignment.
The code to the above is as follows:
// Define Setter
Setter setterResultFail = new Setter();
setterResultFail.Property = DataGridCell.BackgroundProperty;
setterResultFail.Value = Brushes.Red;
// Create a column for the Site.
var currentColumn = new DataGridTextColumn();
currentColumn.Header = "Device #";
currentColumn.Binding = new Binding("Device");
ResultsDataGrid.Columns.Add(currentColumn);
// Create a column for the Site.
currentColumn = new DataGridTextColumn();
currentColumn.Header = "Site";
currentColumn.Binding = new Binding("Site");
ResultsDataGrid.Columns.Add(currentColumn);
// Create a column for the Pass Fail.
currentColumn = new DataGridTextColumn();
currentColumn.Header = "Pass Fail";
currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
// Create cellstyle to make the cell 'red' when the PassFail value is False. ( this is done via a data trigger )
cellStyle = new Style(typeof(DataGridCell));
// Define First DataTrigger that sets a CELL red if the value is a fail.
dataTrigger = new DataTrigger();
dataTrigger.Value = "False";
dataTrigger.Binding = new Binding("PassFail");
dataTrigger.Setters.Add(setterResultFail);
// Add the data-triggers to the cell style.
cellStyle.Triggers.Clear();
cellStyle.Triggers.Add(dataTrigger);
// Apply the newly created cell style.
currentColumn.CellStyle = cellStyle;
ResultsDataGrid.Columns.Add(currentColumn);
Clearly the new cellStyle is used instead of the MaterialDesign style. I've tried setting the values for vertical / horizontal manually but I can't get it to look correct:
Setter setterTextContentHorizonalAlignment = new Setter();
setterTextContentHorizonalAlignment.Property = DataGridCell.HorizontalContentAlignmentProperty;
setterTextContentHorizonalAlignment.Value = HorizontalAlignment.Center;
Setter setterTextContentVerticalAlignment = new Setter();
setterTextContentVerticalAlignment.Property = DataGridCell.VerticalContentAlignmentProperty;
setterTextContentVerticalAlignment.Value = VerticalAlignment.Center;
Setter setterTextHorizontalAlignment = new Setter();
setterTextHorizontalAlignment.Property = DataGridCell.HorizontalAlignmentProperty;
setterTextHorizontalAlignment.Value = HorizontalAlignment.Center;
Setter setterTextVerticalAlignment = new Setter();
setterTextVerticalAlignment.Property = DataGridCell.VerticalAlignmentProperty;
setterTextVerticalAlignment.Value = VerticalAlignment.Center;
cellStyle.Setters.Add(setterTextContentHorizonalAlignment);
cellStyle.Setters.Add(setterTextContentVerticalAlignment);
cellStyle.Setters.Add(setterTextHorizontalAlignment);
cellStyle.Setters.Add(setterTextVerticalAlignment);
Is there a way I can add to the style rather than replace it...similar to the BasedOn approch in XAML?
After much wasting of time on this question I came across Danny Beckett's similar question and King King's answer. By using his answer and applying it to the specific cell I was having trouble with it fixed the issue:King King's answer
// Create a column for the Pass Fail.
currentColumn = new DataGridTextColumn();
currentColumn.Header = "Pass Fail";
currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
// Create cellstyle to make the cell 'red' when the PassFail value is False. ( this is done via a data trigger )
cellStyle = new Style(typeof(DataGridCell));
// Define First DataTrigger that sets a CELL red if the value is a fail.
dataTrigger = new DataTrigger();
dataTrigger.Value = "False";
dataTrigger.Binding = new Binding("PassFail");
dataTrigger.Setters.Add(setterResultFail);
// Add the data-triggers to the cell style.
cellStyle.Triggers.Clear();
cellStyle.Triggers.Add(dataTrigger);
//root visual of the ControlTemplate for DataGridCell is a Border
var border = new FrameworkElementFactory(typeof(Border));
border.SetBinding(Border.BorderBrushProperty, new Binding("BorderBrush")
{
RelativeSource = RelativeSource.TemplatedParent
});
border.SetBinding(Border.BackgroundProperty, new Binding("Background") { RelativeSource = RelativeSource.TemplatedParent });
border.SetBinding(Border.BorderThicknessProperty, new Binding("BorderThickness") { RelativeSource = RelativeSource.TemplatedParent });
border.SetValue(SnapsToDevicePixelsProperty, true);
//the only child visual of the border is the ContentPresenter
var contentPresenter = new FrameworkElementFactory(typeof(ContentPresenter));
contentPresenter.SetBinding(SnapsToDevicePixelsProperty, new Binding("SnapsToDevicePixelsProperty") { RelativeSource = RelativeSource.TemplatedParent });
contentPresenter.SetBinding(VerticalAlignmentProperty, new Binding("VerticalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent });
contentPresenter.SetBinding(HorizontalAlignmentProperty, new Binding("HorizontalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent });
//add the child visual to the root visual
border.AppendChild(contentPresenter);
//here is the instance of ControlTemplate for DataGridCell
var template = new ControlTemplate(typeof(DataGridCell));
template.VisualTree = border;
//define the style
cellStyle.Setters.Add(new Setter(TemplateProperty, template));
cellStyle.Setters.Add(new Setter(VerticalContentAlignmentProperty, VerticalAlignment.Center));
cellStyle.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
// Apply the newly created cell style.
currentColumn.CellStyle = cellStyle;
I'm using GridView with a ListView control to show some catalog content. I'm loading the ListView content dynamically with code behind, creating GridViewColumns and binding them to properties in my custom catListItem class.
var view = new GridView();
var binding = new Binding("Name");
var resElement = _mResourceManager.GetElementByMdlID("vlu_usw_name_of");
view.Columns.Add(new GridViewColumn { Header = resElement.Name, DisplayMemberBinding = binding });
binding = new Binding("Number");
resElement = _mResourceManager.GetElementByMdlID("vlu_usw_arc_logical_nmbr");
view.Columns.Add(new GridViewColumn { Header = resElement.Name, DisplayMemberBinding = binding });
Everything is fine, but now I'm trying to add column with some icon, using the CellTemplate property of the GridViewColumn. Something like this:
var view = new GridView();
var col = new GridViewColumn { Header = "" };
var template = new System.Windows.DataTemplate(typeof(Image));
col.CellTemplate = template;
view.Columns.Add(col);
var binding = new Binding("Name");
var resElement = _mResourceManager.GetElementByMdlID("vlu_usw_name_of");
view.Columns.Add(new GridViewColumn { Header = resElement.Name, DisplayMemberBinding = binding });
binding = new Binding("Number");
resElement = _mResourceManager.GetElementByMdlID("vlu_usw_arc_logical_nmbr");
view.Columns.Add(new GridViewColumn { Header = resElement.Name, DisplayMemberBinding = binding });
I know there's a priority when using DisplayMemberBinding, CellTemplate and CellTemplateSelector.
So my question is:
How can I create (set, ...) content of the CellTemplate and probably bind it to a property of my custom class dynamically? I don't know what do I miss! I've searched for that issue, but everything I found is XAML solutions using DataTemplate.
It's important to do it with code behind.
Thanks in advance!
Actually I found the solution
HERE
I had to use FrameworkElementFactory. Here's the code I was looking for:
var column = new GridViewColumn { Header = "" };
var customTemplate = new System.Windows.DataTemplate();
var efImage = new FrameworkElementFactory(typeof(Image));
efImage.SetBinding(Image.SourceProperty, new Binding("Icon"));
customTemplate.VisualTree = efImage;
column.CellTemplate = customTemplate;
view.Columns.Add(column);
I got a problem with my datagrid. When i click on an element my row become selected and my selected style apply.
but when i scroll, if the element is there again (not duplicate value, item reference are the same), it become in blue, like selected default style.
Having the same item highlight is not a problem, but i would like to put my selected style (the violet dot in row header). In debug, the rows in blue are not selected (and if they were my style would apply). What is the property for being highlight for the duplicate object.
Edit
Binding oBindRowSelected = new Binding();
Binding oBindCellSelected = new Binding();
Binding oBindBackGround = new Binding();
Binding oBindBorderBrush = new Binding();
Binding oBindForeGround = new Binding();
oBindRowSelected.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridRow), 1);
oBindCellSelected.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridCell), 1);
oBindRowSelected.Path = new PropertyPath(DataGridRow.IsSelectedProperty);
oBindCellSelected.Path = new PropertyPath(DataGridCell.IsSelectedProperty);
oBindBackGround.Path = new PropertyPath(DataGridRow.BackgroundProperty);
oBindBorderBrush.Path = new PropertyPath(DataGridRow.BorderBrushProperty);
oBindForeGround.Path = new PropertyPath(DataGridRow.ForegroundProperty);
DataTrigger oTriggerSelectedImageVisibility = new DataTrigger();
oTriggerSelectedImageVisibility.Binding = oBindRowSelected;
oTriggerSelectedImageVisibility.Value = true;
oTriggerSelectedImageVisibility.Setters.Add(new Setter(Border.VisibilityProperty, Visibility.Visible));
DataTrigger oTriggerSelectedCell = new DataTrigger();
oTriggerSelectedCell.Binding = oBindRowSelected;
oTriggerSelectedCell.Value = true;
oTriggerSelectedCell.Setters.Add(new Setter(DataGridCell.BackgroundProperty, oBindBackGround));
oTriggerSelectedCell.Setters.Add(new Setter(DataGridCell.BorderBrushProperty, oBindBorderBrush));
oTriggerSelectedCell.Setters.Add(new Setter(DataGridCell.ForegroundProperty, oBindForeGround));
Style oRowHeaderSelectorStyle = new Style(typeof(Border));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(7)));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.HeightProperty, 15.0));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.WidthProperty, 15.0));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.BackgroundProperty, Brushes.BlueViolet));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.VisibilityProperty, Visibility.Hidden));
oRowHeaderSelectorStyle.Triggers.Add(oTriggerSelectedImageVisibility);
ControlTemplate oCtlTemplate = new ControlTemplate();
FrameworkElementFactory oBorder = new FrameworkElementFactory(typeof(Border));
oBorder.SetValue(Border.StyleProperty, oRowHeaderSelectorStyle);
oCtlTemplate.VisualTree = oBorder;
Style oRowHeaderStyle = new Style(typeof(DataGridRowHeader));
oRowHeaderStyle.Setters.Add(new Setter(DataGridRowHeader.WidthProperty, 25.0));
oRowHeaderStyle.Setters.Add(new Setter(DataGridRowHeader.TemplateProperty, oCtlTemplate));
Style oCellStyle = new Style(typeof(DataGridCell));
oCellStyle.Triggers.Add(oTriggerSelectedCell);
this.RowHeaderStyle = oRowHeaderStyle;
this.CellStyle = oCellStyle;
I am working in an extension, so my style is in C# code.
How can I center the text of ComboBox columns in a DataGridView?
The DataGrid is dynamically updated with columns of different types:
foreach (Fields field in fields)
{
if (field.group.Count > 1)
{
DataGridComboBoxColumn column = new DataGridComboBoxColumn();
column.Header = field.name;
column.ItemsSource = field.group;
column.SelectedValueBinding = new Binding(field.name)
{
};
dgwDataMain.Columns.Add(column);
}
else
{
DataGridTextColumn column = new DataGridTextColumn();
column.Header = field.name;
column.Binding = new Binding(field.name)
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
NotifyOnSourceUpdated = true,
NotifyOnTargetUpdated = true
};
dgwDataMain.Columns.Add(column);
}
}
Solution for WinForm DataGridView:
In your code where you creating a ComboBox columns add next row:
column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter