I have created a ListView with a GridView in code.
ListView gridList = new ListView();
GridView gridListView = new GridView ();
gridList.View = gridListView;
Now, I define a GridViewColumn, set the header, width and bindingPath. All good and the data shows up.
GridViewColumn listColumn = new GridViewColumn();
listColumn.Header = "Some Header";
listColumn.Width = 100.0;
listColumn.DisplayMemeberBinding = new Binding("Name");
gridListView.Columns.Add(listColumn);
But there are no borders/gridlines shown on display of this ListView. How can I add borders through code?
Someone described my exact problem here but no good solution mentioned
http://social.msdn.microsoft.com/Forums/en-US/fa4fa8e0-81fe-487a-8763-590062d29c06/wpf-listview-gridview-row-border?forum=wpf
The logic in WPF programming is totally different from what you've done in winforms. Everything related to UI should always be set up using XAML (as much as possible). The WPF library itself has many parts desgined mainly for use in XAML although there is always an equivalent codebehind. However that's when using codebehind may be awkward and non-intuitive (as well as straight-forward).
I understand that you want something like the ListView Grid in Winforms. In WPF that can be achieved easily if you use XAML code. Even in code behind, you can always build a Style or Template from XAML string (with the help of XamlReader). This approach is good for complex scenario but in this case I have another approach (don't use the XAML parser at all). This trick does render the grid which is good enough (and at best it can do for the trade-off of simplicity):
//we need an instance of Style to set to ListView.ItemContainerStyle
var style = new Style(typeof(ListViewItem));
//set the bottom border thickness to 1
var setter = new Setter(Control.BorderThickness, new Thickness(0,0,0,1));
style.Setters.Add(setter);
//set the border brush
var borderBrush = new LinearGradientBrush { StartPoint = new Point(0,0),
EndPoint = new Point(1,0)};
var gradStop = new GradientStop(Colors.Transparent, 0.001);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Green, 0.001);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Green, 0.999);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Transparent, 0.999);
borderBrush.GradientStops.Add(gradStop);
setter = new Setter(Control.BorderBrush, borderBrush);
style.Setters.Add(setter);
yourListView.ItemContainerStyle = style;
Note that the default inner Border of each ListViewItem has a hard-coded CornerRadius of about 2, so by setting just the bottom BorderBrush to a solid brush such as Brushes.Green will show a little upwards curly line at the 2 ends of the bottom border. You can try it yourself. If this result is acceptable, the code can be shorter and simpler (because you don't have to define the GradientBrush to cut-off the 2 curly ends) like this:
setter = new Setter(Control.BorderBrush, Brushes.Green);
style.Setters.Add(setter);
If the behavior is still not what you want. You should try the approach I mentioned about using XamlReader to parse a XAML string and get an instance of whatever you want in codebehind. (you can search it yourself, it's easy to have some result).
I suggest you see this link, it contains a dynamic GridView created in code-behind that can be useful for your specific case. For the code sample that you provided, you didn't add ShowGridLines property.
I am trying to make the column headers of my DataGridView bold, in Visual Studio 2008.
Every time I change my ColumnHeadersDefaultCellStyle to Calibri 9.75pt bold, using the properties box, the next time I reopen the saved form, the ColumnHeadersDefaultCellStyle has reverted to Calibri 9.75 without bold.
My form's font is Calibri 9.75 without bold, as is my default cell style, but I should be able to override the default cell style with my ColumnHeader style right?
I can solve this problem programmatically by setting the style when the form is shown, but we would like to have the Visual Studio designer show the bolded headers, so we can layout the columns appropriately for the space taken up by bold header text.
In addition, the actual designer file specifies that the ColumnHeadersDefaultCellStyle is bold, even though the designer interface says it is not bold.
dataGridViewCellStyle1.Font = new System.Drawing.Font("Calibri", 9.75F,
System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.receiptDetailView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
Have you tried check EnableHeadersVisualStyles value?
According to MSDN:
If visual styles are enabled and EnableHeadersVisualStyles is set to
true, all header cells except the TopLeftHeaderCell are painted using
the current theme and the ColumnHeadersDefaultCellStyle values are
ignored.
It is a bug, although Microsoft would probably try to call it a feature. The DataGridView header cells are supposed to inherit the current theme only if EnableHeadersVisualStyles is set to TRUE, and use the settings in ColumnHeaderDefaultCellStyles if it is false. But the DGV ignores EnableHeadersVisualStyles and always inherits the font of the parent container it resides in.
Both rutlean's and Nico Engler suggestions will work. Here is what I always do as a standard practice: Put your DGV in a panel (depending on your application, you might want to set the Dock property to fill. Then set the Panel's font to your desired settings. Your DGV will now always inherit that setting.
I found a workaround where just editing the XXXX.Designer.cs with following code does the trick.
this.receiptDetailView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
this.receiptDetailView.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("Calibri", 9.75F, System.Drawing.FontStyle.Bold);
It seems that this is a bug, though I am not sure why it happens. I have tested it in every possible way and the value is overriden by the parent control value regardless of whether it is set or not. This is the opposite of how every other WinForms (or any other UI framework) control works, and doesn't make any sense. I have also tested various other controls and have not found another case where this happens.
The ColumnHeadersDefaultCellStyle Font only matters if the Font property is not set on the parent control (form in this case).
I am giving the bounty to the most upvoted answer but that is not what's going on here.
The "solution" to this that I've been using is to set the font again in the form load event, however this is not a perfect solution since such code doesn't belong there.
I ran into this same issue. However, my dataGridView is located in a groupbox. On a restart of VS 2010, the dataGridView fonts will always be whatever the groupBox is set to. Definitely a bug I would like.
I resolved this problem by adding a frame. For me, the datagridview was inside a groupbox (although a few other container types did the same).
Resolved by putting a panel inside the groupbox, set the appropriate font to that panel, put the datagridview inside that panel and by default it inherits the fonts.
I am using VS2010
The answer is actually pretty simple.
You set a Font Style to Form1 [Arial; 8,25pt].
Lets see the designer :
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Calibri", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2,
this.Column3});
this.dataGridView1.EnableHeadersVisualStyles = false;
this.dataGridView1.Location = new System.Drawing.Point(49, 62);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.Size = new System.Drawing.Size(443, 309);
this.dataGridView1.TabIndex = 0;
//
// Column1
//
this.Column1.HeaderText = "Column1";
this.Column1.Name = "Column1";
//
// Column2
//
this.Column2.HeaderText = "Column2";
this.Column2.Name = "Column2";
//
// Column3
//
this.Column3.HeaderText = "Column3";
this.Column3.Name = "Column3";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 14F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(546, 457);
this.Controls.Add(this.dataGridView1);
this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
Now as you can see, your font setting for Datagridview header did saved.
But still, font setting for your form appeared after that, which eventually overrides Datagridview font setting.
My advice is return the Form font setting to default.
Use this code
dataGridView1.EnableHeadersVisualStyles = false;
dataGridView1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
Try this:
DataGridView1.ColumnHeadersDefaultCellStyle.Font = new Font("Calibri", 9.75F, FontStyle.Bold);
This is a bug and still there even in .net 4.6, the problem is that the ColumnHeadersDefaultCellStyle font always overwritten by its Parent font so I figured out a fix for this:
First you need to add your DataGridView to an own Panel, the Panel will work here as a shield and I believe you need to set the Dock property of the DataGridView to Fill.
Second you need to add the following code into ColumnHeadersDefaultCellStyleChanged event.
If Parent IsNot Nothing Then
Parent.Font = ColumnHeadersDefaultCellStyle.Font
End If
I had the same issue today and it seemed that the ColumnHeadersDefaultCellStyle of the DataGridView is overwritten by the font style of the form it belongs to.
As a solution I set the GdiCharSet parameter of the form's font to 0. After that beeing done, the font of the ColumnHeadersDefaultCellStyle won't be overwritten.
I'm on VS 2010 and Window 8.
I know this topic is old, however I was having the same issue in VS 2015 with the ColumnDefaultHeadersCellStyle font size always reverting to 10pt (I needed it to be 14pt). I was able to fix this by first changing the font itself, which then allowed me to change the font size.
The font I was originally using was SEGOE UI SEMIBOLD, which I changed to just SEGOE UI and was able to change the size. I haven't looked into why using the semibold version prevented me from changing the size. Further, this method has worked for me with VisualStyles enabled, and EnableHeadersVisualStyles set to true.
If anyone is still having this problem, my suggestion would be try changing to another font.
You can try that;
Private Sub DgvListeFt_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DgvListeFt.CellPainting
Call KolonBaslikDGV(sender, e)
End Sub
Sub KolonBaslikDGV(ByVal S As Object, ByVal E As DataGridViewCellPaintingEventArgs)
E.PaintBackground(E.CellBounds, True)
If E.RowIndex = -1 Then
If E.Value Is Nothing Then
E.Handled = True
Return
End If
E.Handled = True
Dim headerFont = New Font("Ariel", 9, FontStyle.Regular)
Dim myBounds As Rectangle = E.CellBounds
myBounds.X = E.CellBounds.X + 4
Dim sf = New StringFormat With {.Alignment = StringAlignment.Near,
.LineAlignment = StringAlignment.Center}
E.Graphics.DrawString(E.Value.ToString, headerFont, Brushes.MediumVioletRed, myBounds, sf)
headerFont.Dispose()
sf.Dispose()
End If
End Sub
I would like to programmatically change content of button via style change. I created a style, added setter for Button.ContentProperty, set new style to button, but content was not changed.
I know that I can set button content directly, but now I would like to know why this does not work:
Style aStyle = new Style();
Setter bSetter = new Setter();
bSetter.Property = Button.ContentProperty;
bSetter.Value = "Some Text";
aStyle.Setters.Add(bSetter);
aButton.Style = aStyle;
XAML:
<Button x:Name="aButton" Style="{x:Null}" Click="Button_Click" />
I could change appearance of a button this way, but I couldn't change content. Btw, I found example in MCTS book on WPF.
Any idea?
This code works for me as is. Are you sure you're not changing Content from other place? you can try
var source = DependencyPropertyHelper.GetValueSource(aButton, ContentControl.ContentProperty);
... to figure it out. I prefer to use WPF snoop for this.
Well, today I found out that there is order of precedence when setting property values in WPF. There is number of mechanisms for setting property value and property value depends on how it was set, not when it was set.
Setting property value in XAML or through code will always precede values set by Style (and templates and triggers). That is, when property value is set in XAML or through code, it cannot be overridden by setting style.
To be able to change property value with mechanism of lower precedence, value must be cleared with DependencyObject.ClearValue method.
In my code example above there was one other method that set Button.Content property in code, so style could not change it any more. Solution for this is to add ClearValue method:
Style aStyle = new Style();
Setter bSetter = new Setter();
bSetter.Property = Button.ContentProperty;
bSetter.Value = "Some Text";
aStyle.Setters.Add(bSetter);
aButton.ClearValue(ContentProperty); // <<-- Added this line to clear button content
aButton.Style = aStyle;
I have a application where user can set the datagrid header background color in runtime. How can I do this? I tried the same through the following code but it is throwing exception.I have used binding and but it's not working.
var style = this.Resources["DataGridHeaderStyle"] as Style;
style.Setters.SetValue(DataGridColumnHeader.BackgroundProperty, "Red");
Without further details (such as the exception you are getting) its difficult to see why you are getting an exception. I suspect that the style variable has a null reference.
I also suspect that the reason its null is that the "DataGridHeaderStyle" doesn't exist in the resource dictionary of the this object, which I would guess is a UserControl. In order to acquire the Style you need to do this look up on the actual FrameworkElement object that holds the Style in its Resources property. (Note programmatic access to the resources does not cascade up the visual tree searching the resource of parents).
However, assuming you can fix that you still have a problem. The use of SetValue on the Setters colleciton itself is nothing like what you actually need to be doing.
You need to be doing this:-
style.Setters.Add(new Setter(DataGridColumnHeader.BackgroundProperty, new SolidColorBrush(Colors.Red));
Of course this only works if the style doesn't already contain an Setter for the property. Hence a more robust version is:-
var setter = style.Setters
.OfType<Setter>()
.Where(s => s.Property == DataGridColumnHeader.BackgroundProperty)
.FirstOrDefault();
if (setter != null)
setter.Value = new SolidColorBrush(Colors.Red);
else
style.Setters.Add(new Setter(DataGridColumnHeader.BackgroundProperty, new SolidColorBrush(Colors.Red));
Good afternoon all,
I have to work with a legacy Winforms application but I'd like to start migrating it to WPF. It doesn't have a tooltip control now so I'd like to use a WPF tooltip object.
I create a single global instance of a tooltip object. I've bound the controls within it and my application sets the datacontext of the tooltip. I can manually show and hide the tooltip just fine. The first time I hover over an object it picks up the bound data perfectly and works great. When I move over another control the tooltip datacontext is changed but the displayed data is never reloaded.
I tried implementing a property changed event and use the INotifyPropertyChanged interface in the object I bind to. It appears the wpf tooltip is not listening to the event.
I tried setting the binding mode to Oneway (it's a display only tooltip).
The tooltip is created programmatically:
// build the tooltip window.
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
img.Width = 50;
img.Height = 60;
// bind the image
System.Windows.Data.Binding imageBinding = new System.Windows.Data.Binding("PatientImage.Data");
imageBinding.Mode = System.Windows.Data.BindingMode.OneWay;
imageBinding.Source = bed;
img.SetBinding(System.Windows.Controls.Image.SourceProperty, imageBinding);
// wrap image in a border
System.Windows.Controls.Border brdr = new System.Windows.Controls.Border();
brdr.BorderBrush = System.Windows.Media.Brushes.Blue;
brdr.Margin = new System.Windows.Thickness(6);
brdr.Child = img;
System.Windows.Controls.WrapPanel wp = new System.Windows.Controls.WrapPanel();
System.Windows.Controls.TextBlock tb = new System.Windows.Controls.TextBlock();
tb.Background = System.Windows.Media.Brushes.LightBlue;
tb.Foreground = System.Windows.Media.Brushes.Blue;
// bind the text block
System.Windows.Data.Binding textBlockBinding = new System.Windows.Data.Binding("TooltipText");
textBlockBinding.Mode = System.Windows.Data.BindingMode.OneWay;
textBlockBinding.Source = bed;
tb.SetBinding(System.Windows.Controls.TextBlock.TextProperty, textBlockBinding);
wp.Children.Add(brdr);
wp.Children.Add(tb);
bedTooltip = new System.Windows.Controls.ToolTip();
bedTooltip.Content = wp;
Any idea why this doesn't work? Maybe I need to use a tooltip object for each control instead of a single global one as a workaround?
The bindings specify a Source, because of that they no longer "care" about the DataContext and hence the bindings do not update if anything other than the property itself on the source-object changes.