Hi,
I’ve made a custom control with the following controltemplate and all painting in OnRender.
Now my problem is, that I can’t select these nodes with the Rubberband. If I clickselect the node all works well, but if I use the Rubberband I can’t select the nodes where the custom control is shown in.
Hi Walter I have Data Templates with Buttons in it and Data Templates with Slider in it - they are selected by the rubberband. But the DataTemplate with my CustomControl (inherited from RangeBase) gets not selected by the rubberband.
In the Button DataTemplate PegelControl is exchanged by Button (and of course some other properties - Button has no TickPlacement and so on), but the rest is identical.
My guess is that your control doesn’t have the actual size that you think it is. What are its ActualWidth and ActualHeight? Also, is the Node.Bounds what you would think it should be?
Hi Walter,
you are right - the DesiredSize of the Border (which is the rootelement of the ControlTemplate) is 0; 0.
On the Node with the Slider it is 40; 20.
Hi Walter,
I get in big trouble here.
If I draw the two lines all is working well. As soon as I change the two lines to a simple Rect (drawed in OnRender with dc.DrawRectangle the selection with the Rubberband doesn’t work.
It’s even getting better!
Please see the attached video (video)
My Control is getting selected if I don’t draw any visible rect in OnRender.
In the video you can see my control on the left with no rect in the middle. It get’s selected by the rubberband.
Now I change a value in the control what leads to draw a rect in the middle and it can’t be selected by the rubberband, just by click.
I really have no Idea what to do.
Remark: If I change the DrawRectangle to DrawLine and give the Pen the Width from the rectangle it’s also working - it must have something to do with the Rect!
In the meantime, does your control draw a background, or does one of its containing panels have a background? Try setting Background=“White” or Background=“Transparent”.
Hi Walter,
it seems that it is the Pen used to draw the rectangle. If it has a Thickness of 0.0 the rubberband can’t select. If it has any value greater than 0.0, or give it a null pen, it works.
Hi Walter,
I modified another CustomControl I found on the Internet to help you reproduce the problem. If you put this in a template for a node and change the Pens Thickness in OnRender to 0.0 you should see the effect.
using System;
using System.Windows;
using System.Windows.Media;
namespace My.Controls
{
public class MyElement : FrameworkElement
{
private static FrameworkPropertyMetadata childMetadata =
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsParentArrange,
OnChildChanged);
public static void OnChildChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MyElement thisElement = obj as MyElement;
if (thisElement == null)
throw new Exception("Child property must be attached to MyElement");
// Remove old one
Visual oldChild = e.OldValue as Visual;
if (oldChild != null)
{
thisElement.RemoveVisualChild(oldChild);
thisElement.RemoveLogicalChild(oldChild);
}
// Attach new one
Visual newChild = e.NewValue as Visual;
if (newChild != null)
{
thisElement.AddVisualChild(newChild);
thisElement.AddLogicalChild(newChild);
}
}
public static readonly DependencyProperty ChildProperty =
DependencyProperty.RegisterAttached("Child", typeof(UIElement),
typeof(MyElement), childMetadata);
public static void SetChild(DependencyObject depObj, UIElement value)
{
depObj.SetValue(ChildProperty, value);
}
protected override int VisualChildrenCount
{
get
{
UIElement childElement = (UIElement)GetValue(ChildProperty);
return childElement != null ? 1 : 0;
}
}
protected override Visual GetVisualChild(int index)
{
// (ignoring index)
return (UIElement)GetValue(ChildProperty);
}
protected override Size MeasureOverride(Size availableSize)
{
UIElement childElement = (UIElement)GetValue(ChildProperty);
if (childElement != null)
childElement.Measure(availableSize);
// "X" and child both use all of the available space
return availableSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
UIElement childElement = (UIElement)GetValue(ChildProperty);
if (childElement != null)
childElement.Arrange(new Rect(new Point(0.0, 0.0), finalSize));
return finalSize;
}
// Render a big "X"
protected override void OnRender(DrawingContext dc)
{
//dc.DrawLine(new Pen(Brushes.Blue, 2.0),
// new Point(0.0, 0.0),
// new Point(ActualWidth, ActualHeight));
//dc.DrawLine(new Pen(Brushes.Green, 2.0),
// new Point(ActualWidth, 0.0),
// new Point(0.0, ActualHeight));
dc.DrawRectangle(Brushes.Blue, new Pen(Brushes.Green, 0.01), new Rect(new Point(0,0), new Point(ActualWidth, ActualHeight)));
}
}
}
That MyElement control that you quoted is incorrectly implemented, because its MeasureOverride can return Infinity when the availableSize is Infinity (either or both Width and Height).
Still, when I use it in my node DataTemplate with a defined size:
<local:MyElement Width="60" Height="30" />
I find that the DragSelectingTool works well on such nodes.