Hi,
I have a template for my node with a Label-Control in it.
Now the text in the label is very long. But the size of the node is much samler than needed to fully display the text. If I now want to drag select this node it only get selected if the select rectangle is covering the whole (invisible) text.
Is there a way for the node to get selected when the select rectangle is cover only the dimensions of the node?
I hope you understand what I try to discribe.
The node
|
˅
+--------------+
| This is the intern Label with long text
+--------------+
And this node get selected by the dragselectingtool only if the selecting rectangle covers the whole text although the text (ntern Label with long text) is not visible cause the node dimension are smaller.
Hi Walter,
at the moment I don’t want to use intersects cause I don’t want to select any underlying nodes.
The Node bounds are ok, but the contentPresenter of the inner button has a textblock and this textblock has a much larger width than the node.
I have no idea what to do - I thought the nodebounds are responsible for the selection.
DragSelectingTool.SelectInRect calls DiagramPanel.FindPartsIn which calls VisualTreeHelper.HitTest. I’m surprised this isn’t working for you.
I was going to suggest overriding SelectInRect next, which apparently you have already done. However, what you have implemented will leave previously selected Parts still selected, which might not be your intent.
Ah, right – I missed the base call, which I think might not be necessary if you cleared out the selection beforehand. However in either case it doesn’t handle modifiers. Here’s the complete definition:
public virtual void SelectInRect(Rect r) {
Diagram diagram = this.Diagram;
if (diagram == null) return;
// choose the selectable Parts within the rectangle
HashSet<Part> parts = new HashSet<Part>(diagram.Panel.FindPartsIn<Part>(r, SearchFlags.SelectableParts, this.Include, SearchLayers.Parts));
if (IsControlKeyDown()) { // toggle or deselect
if (IsShiftKeyDown()) { // deselect only
foreach (Part p in parts) {
if (p.IsSelected) p.IsSelected = false;
}
} else { // toggle selectedness of parts
foreach (Part p in parts) {
p.IsSelected = !p.IsSelected;
}
}
} else if (IsShiftKeyDown()) { // extend selection only
foreach (Part p in parts) {
if (!p.IsSelected) p.IsSelected = true;
}
} else { // select parts, and unselect all other previously selected parts
// this tries to avoid deselecting and then reselecting any Part
List<Part> tounselect = new List<Part>();
foreach (Part p in diagram.SelectedParts) {
if (!parts.Contains(p)) tounselect.Add(p);
}
foreach (Part p in tounselect) {
p.IsSelected = false;
}
foreach (Part p in parts) {
if (!p.IsSelected) p.IsSelected = true;
}
}
}
I’ll assume BooleanNegationConverter negates a boolean value.
So the Label will not be “hittable”, which will cause any hit-testing on the text to fail, even though the Label still takes up most of the space of the Node.
Even the Hittest is set to false the node only get selected if the selection rect of dragselectiontool covers the whole bounds of the partly not visible text.
ClickSelecting is no problem! The node only get selected if someone is clicking inside the node bound (textbounds does not matter).
I think the problem is that the Label is really long, so as far as hit-testing goes, the node is effectively very big, even if the top-level visual element is relatively small because it clips the long Label.
What you have done to override SelectInRect is the right solution.
public override void SelectInRect(Rect r)
{
Diagram diagram = this.Diagram;
if (diagram == null) return;
// choose the selectable Parts within the rectangle
HashSet<Part> parts = new HashSet<Part>(Diagram.PartManager.Nodes.Where(p => r.Contains(p.Bounds.TopLeft) && r.Contains(p.Bounds.BottomRight) && p.Selectable));
if (IsControlKeyDown())
{ // toggle or deselect
if (IsShiftKeyDown())
{ // deselect only
foreach (Part p in parts)
{
if (p.IsSelected) p.IsSelected = false;
}
}
else
{ // toggle selectedness of parts
foreach (Part p in parts)
{
p.IsSelected = !p.IsSelected;
}
}
}
else if (IsShiftKeyDown())
{ // extend selection only
foreach (Part p in parts)
{
if (!p.IsSelected) p.IsSelected = true;
}
}
else
{ // select parts, and unselect all other previously selected parts
// this tries to avoid deselecting and then reselecting any Part
List<Part> tounselect = new List<Part>();
foreach (Part p in diagram.SelectedParts)
{
if (!parts.Contains(p)) tounselect.Add(p);
}
foreach (Part p in tounselect)
{
p.IsSelected = false;
}
foreach (Part p in parts)
{
if (!p.IsSelected) p.IsSelected = true;
}
}
}
Just the line with filling the hashset is different from the original.