WPF Border Property not working correctly - c#

I am working on an application that is using Drag and Drop functionality. When I drag certain items over other items, I would like to show if they are towards the top, or the bottom of the item by setting the border property of the item they are over dynamically(as oppose to in the xaml).
I have looked into this, and used examples, but none of them are working. Here is the code I have that is called when a drag operation is performed over the Grid Item.
private void Grid_DragEnter(object sender, DragEventArgs e)
{
Grid grid = (Grid)sender;
grid.Background = Brushes.Cornsilk;
Border border = new Border();
border.BorderBrush = Brushes.Black;
border.BorderThickness = new Thickness(5, 10, 15, 20);
border.Background = Brushes.Black;
border.Padding = new Thickness(10);
border.Child = grid;
}
The code above is only test code so that I can see the border is showing. Once I can get this, then I will set the top or bottom border at separate times, depending on if they are above or below the center of the grid item.

You're setting the border's child, but the border itself needs to be added to some container in order for it to be visible.
That being said, you might want to look into Adorners. They are designed for exactly this scenario, and don't require changing the visual hierarchy of your UI at runtime.

Related

TextBlock shown without text in expanded WPF Canvas

I'm using C# with WPF, to draw some graphics and texts into a WPF Canvas.
For adding texts to the canvas I use a TextBlock and this works fine when I don't change the size of the Canvas.
When I extend the width of the canvas, sometimes the text is not drawn (from the x-position where I extended the canvas). The text is there, because I can see the text background (and also a strikethrough which I added for testing).
When I change the length of the text and/or set the TextBlock length in code, the behavior changes. Meaning with some changes the text is shown.
The graphics are shown just fine in all circumstances.
I've tried to make sure the Width and ActualWidth of the Canvas are correct before I draw the texts.
I use this code to draw the text onto the Canvas:
private void drawHeartrate(string hr, double xHr)
{
TextBlock hrTextBlock = new TextBlock();
hrTextBlock.Text = hr;
hrTextBlock.Foreground = Brushes.Black;
hrTextBlock.TextDecorations = TextDecorations.Strikethrough;
hrTextBlock.Background = Brushes.Yellow;
hrTextBlock.FontFamily = new FontFamily("Soho Gothic Pro");
hrTextBlock.FontSize = 14;
Canvas.SetLeft(hrTextBlock, xHr);
Canvas.SetTop(hrTextBlock, -2);
CnvsEcg.Children.Add(hrTextBlock);
}
The screen where the texts is not displayed anymore looks like this (from the above code):
Screenshot of problem text

Animate a label

I am trying to animate a label in a WPF application. The label gets created programatically (and dynamically) so it is not defined in XAML, but is created in the C# code.
Animation Story
The label appears in the bottom of the window. The label should be positioned lower than the window, so the user can not see it initially. Then a the label moves up (like sliding) and fades out before it reaches the top of the window.
What I have done
I have implemented this behavior myself in an other project. This time I want to use WPF which should perform better.
So far I have seen there should be multiple ways of doing this. Starting with a DoubleAnimation, going by a PathAnimation and VectorAnimation (the last of which I have not tested successfully).
Encountered problems
The animation works nice with a DoubleAnimation, but there is a problem: When I resize the window, the label gets resized too (similar to an anchor in Winforms). When I make the window smaller the label gets smaller too, until it disappears completely. This effect occurs only in the height of the label. I added the code snippet adding the label. Maybe you find some error. Also there should be a better way to implement this (I personally find it very ugly).
Label lbl = new Label()
{
Content = "Test",
FontSize = 36,
Foreground = new SolidColorBrush(Colors.Red),
Background = new SolidColorBrush(Colors.Black),
HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center,
VerticalAlignment = System.Windows.VerticalAlignment.Top
};
lbl.Margin = new Thickness(0, this.MainGrid.ActualHeight + lbl.ActualHeight, 0, 0);
this.MainGrid.Children.Add(lbl);
UpdateLayout();
Transform myTransform = new TranslateTransform();
lbl.RenderTransform = myTransform;
DoubleAnimation AnimationY = new DoubleAnimation((this.MainGrid.ActualHeight + 20) * -1, TimeSpan.FromSeconds(4));
myTransform.BeginAnimation(TranslateTransform.YProperty, AnimationY);
Questions
As I said, I have found multiple ways that seem to achieve the same behavior. Which one could I use to do this. I still have to do the fade-out on the top of the window, but this animation is easier to do compared to the movement.
The animation is fine. The reason your label is resizing is because you are adding it to a Grid. If you want your label to have a fixed height, then set its Height or MinHeight property.

ListViewItem loses background color when repainted and the cursor is over the item

I have a listview control obviously with numerous listviewitems, whenever the control is repainted the item which the mouse is "over" at the time loses it's background colour (ie. it's white).
Once the item is painted again and the cursor is not over it the correct background colour is restored.
Does anyone know why this happens and how it can be stopped?
Any help would be appreciated
To expand on this and hopefully give a little more context....
It's happening on Windows 7, .NET 3.5 (although it was also happening when the project was targetted at 4.0 too). The theme on my dev computer is Viao Theme 5, however it also happens on another of my machines which has the default Windows 7 theme.
The listview is instantiated like this...
this.PlaylistTrackList.Cursor = System.Windows.Forms.Cursors.Hand;
this.PlaylistTrackList.Dock = System.Windows.Forms.DockStyle.Fill;
this.PlaylistTrackList.FullRowSelect = true;
this.PlaylistTrackList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.PlaylistTrackList.LabelWrap = false;
this.PlaylistTrackList.Location = new System.Drawing.Point(4, 4);
this.PlaylistTrackList.Margin = new System.Windows.Forms.Padding(4);
this.PlaylistTrackList.MultiSelect = false;
this.PlaylistTrackList.UseCompatibleStateImageBehavior = false;
this.PlaylistTrackList.View = System.Windows.Forms.View.Details;
Let's say there are 5 list view items, A,B,C,D, and E. If the background color property of items BC and D is red, nothing is selected and nothing is going to be selected. When the list view control is redrawn for whatever reason and the cursor happens to be over any of items BC or D then the item is drawn with a white background color not red as it should be. However once the mouse is not over the item again and its redrawn is returns to red.
How can I stop it always drawing the item that the cursor is over with a white background regardless of the "real" background color property?
Initialize the ListView control as follows:
listView1.BackColor = Color.Black;
listView1.ForeColor = Color.White;
listView1.Dock = DockStyle.Fill;
listView1.View = View.Details;
listView1.FullRowSelect = true;
For more details check the following link:
http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.ownerdraw.aspx

Change Border of ToolStripComboBox with Flat Style

I would like to be able to change the border color of ToolStripComboBox controls in some of my toolstrips, since the default border color of ComboBoxes when used with flat styling is SystemColors.Window, which is basically invisible against the default control color of the toolstrip. After a lot of digging around in Reflector, I don't see any obvious way to do this, since all the infrastructure behind ComboBox rendering is highly protected behind internal and private interfaces.
Outside of ToolStrips, a common solution I've seen proposed for fixing border color on ComboBoxes is to subclass ComboBox, override WndProc, and manually paint the border. This can't work for ToolStripComboBox controls since the internal ComboBox control is its own private subclass of ComboBox, with no way that I can see to replace the instance of the control.
An alternative solution I'm considering is putting one of the extended ComboBox objects into a ToolStripControlHost, which allows me to draw a border, but then I have to give up some of the professional renderer tweaks. A secondary drawback I've noticed is that I get occasional flicker during mouseover.
Switching my design to WPF is not an acceptable solution. Wrapping controls in parent controls for drawing borders is also not acceptable, as this gains nothing over the ToolStripControlHost alternative.
Does anyone have a clever solution to defeat this problem, or is there an existing (permissively-licensed) re-implementation of the ComboBox flat-style rendering stack out in the wild, which fixes some of the shortcomings in the existing implementation?
Here's a way to make it work ... sort of :)
Create an event handler for the Paint event of the ToolStrip. Then loop through all of the ToolStripComboBoxes and paint a rectangle around them.
private Color cbBorderColor = Color.Gray;
private Pen cbBorderPen = new Pen(SystemColors.Window);
private void toolStrip1_Paint(object sender, PaintEventArgs e)
{
foreach (ToolStripComboBox cb in toolStrip1.Items)
{
Rectangle r = new Rectangle(
cb.ComboBox.Location.X - 1,
cb.ComboBox.Location.Y - 1,
cb.ComboBox.Size.Width + 1,
cb.ComboBox.Size.Height + 1);
cbBorderPen.Color = cbBorderColor;
e.Graphics.DrawRectangle(cbBorderPen, r);
}
}
Here's what it looks like (note that you may need to adjust the Height of the ToolStrip to prevent the painted border from being cut off):
improvement:
check the type of the toolstrip item,
so the program will not crush if it is toolstipLabel for example.
foreach (var item in toolStrip1.Items)
{
var asComboBox = item as ToolStripComboBox;
if (asComboBox != null)
{
var location = asComboBox.ComboBox.Location;
var size = asComboBox.ComboBox.Size;
Pen cbBorderPen = new Pen(Color.Gray);
Rectangle rect = new Rectangle(
location.X - 1,
location.Y - 1,
size.Width + 1,
size.Height + 1);
e.Graphics.DrawRectangle(cbBorderPen, rect);
}
}
toolStrip1.ComboBox.FlatStyle = FlatStyle.System;
This sets the default, OS-styled, border around the combo box. It is a light grey and thin border on Windows 10. Although, depending on the background, this may not show. In which case, you could try the other options like FlatStyle.Popup.
If the presets aren't what you are looking for, the other answers allow you to draw a custom border. However, since the rectangle is drawn with +1 pixel size around the combo box, the border is 1 pixel larger than the combo box. Removing the +1s and -1s doesn't work either.

Prevent Button from inheriting BackColor of Parent

When I have a parent control which has a BackColor other than SystemColors.Control, but I have buttons on that parent control that I want to be drawn in the system them. However, when I do not change the BackColor of the buttons, it's drawn in the color of the parent. When I change the BackColor of the button to SystemColors.Control, it isn't drawn in the Windows theme anymore.
The left version is with SystemColors.Control and the right is without changing the BackColor.
Blown up, it looks like this. Here you can see that the buttons have a solid background.
Any suggestions how I can fix this?
The effect in the image can be accomplished by creating a new .NET 2.0 WinForms project and changing the constructor of Form1 to the following:
public Form1()
{
InitializeComponent();
var textBox = new TextBox();
Controls.Add(textBox);
var button = new Button { Text = "L", Width = 23, Height = 18, Left = -1, Top = -1 };
textBox.Controls.Add(button);
// Disable the line below to get the default behavior
button.BackColor = SystemColors.Control;
}
I unforuantely only have access to Windows 7 at the moment so I can't test on XP etc. but are you calling Application.EnableVisualStyles in the Main entry point of your WinForms application?
On Windows 7 with Aero enabled the buttons do not assume the parent color if Application.EnableVisualStyles is called.
NB: You should set button.UseVisualStyleBackColor = true; and do not explicitly set the BackColor property of the button.

Categories