I am trying to display different shapes on Content Presenter in wpf, I am able to show Rectangle but Line object is not getting populated, Can anyone help me with this
Line r = new Line();
r.SetValue(Canvas.TopProperty, 50.0);
r.SetValue(Canvas.LeftProperty, 10.0);
r.X1 = 50;
r.Y1 = 50;
r.X2 = 150;
r.Y2 = 150;
r.Width = 200;
r.StrokeThickness = 5.0;
r.Fill = new SolidColorBrush(Colors.Green);
ContentComponent.Content = r;
You should set the Stroke property to a Brush:
r.Stroke = Brushes.Green;
Note that there is no reason to create a new green brush using new SolidColorBrush(Colors.Green) instead of using the static Green property of the Brushes class.
Related
I have a dynamically created WPF Canvas element inside a ContentControl (the same thing happens in a UserControl.) Whenever I attempt to set the background, either upon creation or later on in the program, the background color won't paint (I am however able to set the background on a Label inside of the Canvas (also added dynamically.) The creation code I have looks like:
_rootGrid = new Grid();
_rootGrid.Name = "_rootGrid";
_rootGrid.Margin = new Thickness(0);
_rootGrid.HorizontalAlignment = HorizontalAlignment.Stretch;
_rootGrid.VerticalAlignment = VerticalAlignment.Stretch;
_rootGrid.RowDefinitions.Add(new RowDefinition());
_rootGrid.RowDefinitions.Add(new RowDefinition());
_rootGrid.ColumnDefinitions.Add(new ColumnDefinition());
_rootGrid.RowDefinitions[0].Height = new GridLength(24);
_rootGrid.RowDefinitions[1].Height = new GridLength(0, GridUnitType.Star);
_rootGrid.ColumnDefinitions[0].Width = new GridLength(0, GridUnitType.Star);
_headerBlock = new Canvas();
_headerBlock.Name = "_headerBlock";
_headerBlock.SetValue(Grid.RowProperty, 0);
_headerBlock.SetValue(Grid.ColumnProperty, 0);
_headerBlock.PreviewMouseLeftButtonUp += _headerBlock_PreviewMouseLeftButtonUp;
_headerBlock.Background = Brushes.Red;
_title = new Label();
_title.Name = "_title";
_title.Content = "Title";
_title.VerticalAlignment = VerticalAlignment.Center;
_title.HorizontalAlignment = HorizontalAlignment.Left;
_title.FontWeight = FontWeights.Bold;
_title.Background = Brushes.Blue;
_clientBlock = new ScrollViewer();
_clientBlock.Name = "_clientBlock";
_clientBlock.Margin = new Thickness(0);
_clientBlock.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
_clientBlock.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
_clientBlock.SetValue(Grid.RowProperty, 1);
_clientBlock.SetValue(Grid.ColumnProperty, 0);
_clientArea = new Grid();
_clientArea.Name = "_clientArea";
_clientArea.HorizontalAlignment = HorizontalAlignment.Stretch;
_clientArea.VerticalAlignment = VerticalAlignment.Stretch;
_headerBlock.Children.Add(_title);
_rootGrid.Children.Add(_headerBlock);
_clientBlock.Content = _clientArea;
_rootGrid.Children.Add(_clientBlock);
base.Content = _rootGrid;
And is called inside of the ContentControl constructor. From that I would expect the header to contain a full row of Red with a Blue rectangle around the text, but all I get is the Blue rectangle around text with most of the row left Transparent (noticeable due to the Green background of the root Grid.) Any help on this would be appreciated as it is enormously frustrating. I'm using version 6.2 of the .NET framework on Windows 7 if that plays into it (I have noticed some other odd behaviors, but am going for dynamic generation mostly because these ContentControls take lots of child elements and the VS 2017 XAML parser is too broken to allow them to be named - which makes them virtually useless.)
The solution is to use non-zero Width for ColumnDefinition:
_rootGrid.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star); // equal to Width="*" in xaml
When 0 is used, Canvas has 0 witdh. But is is possible to see blue Label because Canvas doesn't clip contents on its bounds.
If you try Grid (var _headerBlock = new Grid();) with zero width column, there won't be anything displayed at all.
I have a vertical StackPanel and I want it to contain Line-child with .X2 value binded to parent-StackPanel's ActualWidth. Something like:
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Vertical;
(...)
Line line = new Line();
line.X1 = 0;
line.X2 = <Some binding to sp.ActualWidth>;
// line.Y1 = line.Y2 - will it set it's value to 0 by default?
line.StrokeThickness = 2;
(...)
sp.Children.Add(line);
Should I use INotifyPropertyChanged interface? Is this the most proper way?
INotifyPropertyChanged is not necessary.
Just create a binding and setbinding to X2Property of the line.
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Vertical;
Line line = new Line();
line.X1 = 0;
var bind = new Binding()
{
Source = sp,
Path = new PropertyPath("ActualWidth")
};
BindingOperations.SetBinding(line, Line.X2Property, bind);
line.StrokeThickness = 2;
line.Stroke=Brushes.Black;
line.Margin=new Thickness(10);
sp.Children.Add(line);
An alternative to a Line with a bound X2 property and a StrokeThickness of 2 would be a Rectangle with a Height of 2. Its width is automatically set to the StackPanel width.
var sp = new StackPanel
{
Orientation = Orientation.Vertical
};
...
var line = new Rectangle
{
Height = 2,
Fill = Brushes.Black
};
sp.Children.Add(line);
I do not want cut text of textblock. For this reason, I set viewBox.ClipToBounds to false, But it doesn't work.
Please tell me why ClipToBounds=false not work in this code:
private void Btn1_Click(object sender, RoutedEventArgs e)
{
Button button = new Button(); button.Background = Brushes.Red;
button.Width = 70; button.Height = 20;
Canvas.SetLeft(button, 100); Canvas.SetTop(button, 120);
button.Padding = new Thickness(1);
StackPanel stackPanel = new StackPanel();
Viewbox viewBox = new Viewbox();
viewBox.ClipToBounds = false;
Canvas canvas = new Canvas();
canvas.Width = button.Width; canvas.Height = button.Height;
TextBlock textBlock = new TextBlock();
textBlock.Text = "this is a test";
textBlock.FontSize = 15;
textBlock.FontFamily = new FontFamily("Arial");
textBlock.TextWrapping = TextWrapping.NoWrap;
textBlock.Foreground = Brushes.Green;
textBlock.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
textBlock.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
viewBox.Height = 20;
textBlock.IsHitTestVisible = false;
stackPanel.Children.Add(viewBox);
viewBox.Child = canvas;
canvas.Children.Add(textBlock);
button.Content = stackPanel;
Canvas MainCanvas = new Canvas();
MainCanvas.Children.Add(button);
this.Content = MainCanvas;
}
Screenhsot:
The screenshot below is what I want. :
ClipToBounds is false by default. However, clipping can still happen due to the way certain elements perform layout. Basically the way things work in WPF is that setting ClipToBounds = true will force things to clip. Leaving it set to false means that WPF determines how things should clip based on measure constraints and arrange rects.
If you look at the ArrangeCore and MeasureCore methods in FrameworkElement, you will see that there is quite a bit of logic determining whether something should clip. Of course, things that override FrameworkElement are free to render however they want, but generally they will obey the clipping rules established by the base class.
In the case of a TextBlock, it will definitely clip text that goes outside of its bounds if its size is constrained. You can see this by simply setting a Width on it, or placing it is a parent that has a Width set on it.
If you really need the text to render outside of the bounds of the control, you may have to consider something like writing a custom text rendering element.
Even then, it is still going to be clipped by its parent as soon as you place it in something else that clips. So, you could still end up stuck.
You could try placing the TextBlock on top of the button instead of inside of it, and setting its position to get it in the right place (maybe by binding it to something). This would work, but might get hard to manage if you need to do it too much.
Basically, you are trying to go against one of the hard-coded rules of WPF, so you are likely not going to find an easy way to do it. Perhaps you might want to reevaluate your design and determine if this behavior is really necessary for what you want to do, or if you can go about it in a different way.
Thanks to elgonzo and Xavier.
I realized that I should not put the canvas in the viewbox.
By 2 change my problem solved.
1 - Swap viewbox with canvas.
2 - Remove canvas.with = ...
This is correct code :
private void Btn1_Click(object sender, RoutedEventArgs e)
{
Button button = new Button(); button.Background = Brushes.Red;
button.Width = 70; button.Height = 20;
Canvas.SetLeft(button, 100); Canvas.SetTop(button, 120);
button.Padding = new Thickness(1);
StackPanel stackPanel = new StackPanel();
Viewbox viewBox = new Viewbox();
viewBox.ClipToBounds = false;
Canvas canvas = new Canvas();
// canvas.Width = button.Width; canvas.Height = button.Height;
TextBlock textBlock = new TextBlock();
textBlock.Text = "this is a test";
textBlock.FontSize = 15;
textBlock.FontFamily = new FontFamily("Arial");
textBlock.TextWrapping = TextWrapping.NoWrap;
textBlock.Foreground = Brushes.Green;
textBlock.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
textBlock.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
viewBox.Height = 20;
textBlock.IsHitTestVisible = false;
stackPanel.Children.Add(canvas);
viewBox.Child = textBlock;
canvas.Children.Add(viewBox);
button.Content = stackPanel;
Canvas MainCanvas = new Canvas();
MainCanvas.Children.Add(button);
this.Content = MainCanvas;
}
I have a uniform grid that has rectangles dynamically added to it. I want to remove a particular rectangle, but I am getting the following error when trying to pass it to the Remove method:
Cannot convert from 'System.Drawing.Rectangle' to 'System.Windows.UIElement'
My code is:
Rectangle swatch = (Rectangle)ug_Thumbnails.FindName("s_" + _instance);
ug_Thumbnails.Children.Remove(swatch);
I tried casting, and got an error saying that you couldn't do it.
EDIT: Per request, here's the code to create the rectangle:
System.Windows.Shapes.Rectangle swatch = new System.Windows.Shapes.Rectangle();
swatch.Width = 50;
swatch.Height = 50;
swatch.Margin = new Thickness(0, 5, 5, 0);
swatch.StrokeThickness = 1;
swatch.Stroke = System.Windows.Media.Brushes.Gray;
swatch.Name = "s_" + name.ToString();
double groupsize = 100 / colors.Count();
DrawingBrush blackBrush = new DrawingBrush();
DrawingGroup checkersDrawingGroup = new DrawingGroup();
List<SolidColorBrush> brushes = colors;
double location = 0;
for (int i = 0; i < colors.Count(); i++)
{
GeometryDrawing drawing = new GeometryDrawing(brushes[i], null,
new RectangleGeometry(new Rect(location, 0, groupsize, groupsize)));
checkersDrawingGroup.Children.Add(drawing);
location += groupsize;
}
blackBrush.Drawing = checkersDrawingGroup;
swatch.Fill = blackBrush;
swatch.MouseUp += new MouseButtonEventHandler(loadSwatchResources);
ug_Thumbnails.Children.Add(swatch);
You need to use the Rectangle in System.Windows.Shapes when trying to reference a rectangle in WPF. This is specifically for rectangles in WPF and as such is a bit different than the System.Drawing rectangle class. You should be able to cast to this version of rectangle since it derives from FrameworkElement. See http://msdn.microsoft.com/en-us/library/system.windows.shapes.rectangle(v=vs.110).aspx for more info.
In WPF (C#) is there a way to set the tooltip's height and width dynamically (meaning in code). Thanks for the help.
System.Windows.Controls.Image td = new System.Windows.Controls.Image();
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(Directory.GetCurrentDirectory() + "/Homepage.jpg");
td.Width = 530;
td.Height = 392;
//myBitmapImage.DecodePixelWidth = 430;
//myBitmapImage.DecodePixelHeight = 292;
myBitmapImage.EndInit();
td.Source = myBitmapImage;
TextBlock textBlock = new TextBlock();
BrushConverter conv = new BrushConverter();
string strColor1 = bannerColor.SelectedItem.ToString();
strColor1 = strColor1.Substring(strColor1.IndexOf(' ') + 1);
SolidColorBrush col = conv.ConvertFromString(strColor1) as SolidColorBrush;
textBlock.Foreground = col;
textBlock.FontWeight = FontWeights.Bold;
textBlock.FontSize = 18;
textBlock.FontFamily = new System.Windows.Media.FontFamily("Tahoma");
textBlock.Width = 100;
textBlock.Height = 20;
textBlock.Text = "BACKUP";
textBlock.Margin = new Thickness(5, 5, 425, 367);
Grid toolTipPanel = new Grid();
toolTipPanel.Width = 530;
toolTipPanel.Height = 392;
toolTipPanel.Children.Add(td);
toolTipPanel.Children.Add(textBlock);
ToolTipService.SetToolTip(image1, toolTipPanel);
ToolTipService.SetShowDuration(image1, 999999999);`
In your code just set the tooltip's height and width property to Double.NaN to have the width and height adjust dynamically.
_toolTip.Width = Double.NaN;
_toolTip.Height = Double.NaN;
This will do the trick.
A tool tip's height and width are based on its content. So you should simply make the content the size you want it to be.
Perhaps you could post your code that sets the tool tip, for further clarification?