Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic How to bind DiagramNode.Bounds property? (Read 4359 times)
roger huber
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 6
Joined: Nov 8th, 2016
How to bind DiagramNode.Bounds property?
Nov 10th, 2016 at 8:14pm
Print Post  
Hi!

I don't get a binding to work. I set up the binding in my custom Node (that inherrits from DiagramNodeAdapter):

Code
Select All
var boundsBinding = new Binding(nameof(NodeViewModel.Bounds))
{
  Source = NodeViewModel,
  Mode = BindingMode.OneWay,
  Converter = new RelativeToAbsoluteNodePositionConverter(),
  ConverterParameter = NodeViewModel
};
SetBinding(BoundsProperty, boundsBinding);
 



The NodeViewModel's Bounds property value is fetched the very first time after setting the binding (and the converter is executed). However, if I later fire the PropertyChanged event in the NodeViewModel, the property won't be accessed. There are no swallowed binding exceptions and the NodeViewModel that is used as source for the binding is the same instance that fires the PropertyChanged event.

Shouldn't that work?

Thanks,
Roger
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to bind DiagramNode.Bounds property?
Reply #1 - Nov 11th, 2016 at 11:13am
Print Post  
Hi!

Our bad; it should work with this build -
https://mindfusion.eu/_beta/wpfdiag342.zip

Regards,
Slavcho
  
Back to top
 
IP Logged
 
roger huber
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 6
Joined: Nov 8th, 2016
Re: How to bind DiagramNode.Bounds property?
Reply #2 - Nov 16th, 2016 at 3:19pm
Print Post  
Hi Slavcho,

Partial success. Given the structure Diagram->ContainerNode->DiagramNodeAdapter, the DiagramNode.BoundsProperty binding does work now.

But I have still an issues:

As soon as I move ContainerNode, the node that is attached to the ContainerNode is not moved although PropertyChanged event is fired in the NodeViewModel.

Regards,
Roger
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to bind DiagramNode.Bounds property?
Reply #3 - Nov 17th, 2016 at 10:17am
Print Post  
Hi,

Moving the container interactively also moves the child for me. Do you mean moving it through a ContainerNode.Bounds binding too?

Regards,
Slavcho
  
Back to top
 
IP Logged
 
roger huber
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 6
Joined: Nov 8th, 2016
Re: How to bind DiagramNode.Bounds property?
Reply #4 - Nov 17th, 2016 at 11:54am
Print Post  
I attached two pictures. Picture #1 shows the working use case whereas picture #2 shows the use case in that the binding does not work any longer.

In each picture you can see two MindFusion.Diagramming.Wpf.Diagram instances. Moving a node in one diagram will update the second diagram (following the MVVM pattern).
  

works.png ( 22 KB | 133 Downloads )
works.png
DoesNotWork.png ( 22 KB | 118 Downloads )
DoesNotWork.png
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to bind DiagramNode.Bounds property?
Reply #5 - Nov 18th, 2016 at 9:44am
Print Post  
I'm confused by the numbering Smiley Anyway just playing with Bounds and bindings here's what I'm seeing (without involving ContainerNodes) -

1. Mode = BindingMode.OneWay
2. NodeViewModel.Bounds = new_value
3. node.Bounds local value is a BindingExpression, node position updates successfully from it
4. I move the node, Bounds local value becomes a Rect
5. NodeViewModel.Bounds assignment no longer updates node position because BindingExpression has been removed from the dependency property

----------------------------------

1. Mode = BindingMode.TwoWay
2. NodeViewModel.Bounds = new_value
3. node.Bounds local value is a BindingExpression, node position updates successfully from it
4. I move the node, and since binding is two-way the property assignment updates NodeViewModel.Bounds
5. NodeViewModel.Bounds assignment still updates node position because the property local value is a BindingExpression.

So I'm guessing if your binding mode is still OneWay as in first post, try changing it to TwoWay. You can verify if binding is active by examining the result of node.ReadLocalValue(DiagramNode.BoundsProperty) - should be an instance of System.Windows.Data.BindingExpression.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
roger huber
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 6
Joined: Nov 8th, 2016
Re: How to bind DiagramNode.Bounds property?
Reply #6 - Nov 18th, 2016 at 10:57am
Print Post  
Why does moving a MindFusion.Diagramming.Wpf.DiagramNodeAdapter on the canvas replace the BindingExpression by a Rect instance? This is something that I don't expect. I think if I move the ContainerNode, the child node's Bound's property will be changed from BindingExpresson to Rect as well and therefore is not updated any more.

The reason why I'm using BindingMode.OneWay is because I want to set NodeViewModel.Bounds after MindFusion.Diagramming.Wpf.DiagramBase.NodeModified has been fired. I don't want the source of the binding to be updated when the user is still moving a node.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to bind DiagramNode.Bounds property?
Reply #7 - Nov 18th, 2016 at 1:06pm
Print Post  
It's how WPF dependency property system works -

Code
Select All
var depObj1 = new BindTest();
var model1 = new BindTestModel();
var binding1 = new Binding("TestValue")
{
	Source = model1,
	Mode = BindingMode.OneWay
};
depObj1.SetBinding(BindTest.TestValueProperty, binding1);
model1.TestValue = 1;
Debug.WriteLine(depObj1.ReadLocalValue(BindTest.TestValueProperty)); // BindingExpression
depObj1.TestValue = 1;
Debug.WriteLine(depObj1.ReadLocalValue(BindTest.TestValueProperty)); // no longer BindingExpression


var depObj2 = new BindTest();
var model2 = new BindTestModel();
var binding2 = new Binding("TestValue")
{
	Source = model2,
	Mode = BindingMode.TwoWay
};
depObj2.SetBinding(BindTest.TestValueProperty, binding2);
model2.TestValue = 2;
Debug.WriteLine(depObj2.ReadLocalValue(BindTest.TestValueProperty));  // BindingExpression
depObj2.TestValue = 2;
Debug.WriteLine(depObj2.ReadLocalValue(BindTest.TestValueProperty));  // BindingExpression

class BindTest : FrameworkElement
{
	public static DependencyProperty TestValueProperty = DependencyProperty.Register(
		"TestValue", typeof(int), typeof (BindTest));

	public int TestValue
	{
		get { return (int) GetValue(TestValueProperty); }
		set { SetValue(TestValueProperty, value); }
	}
}

class BindTestModel : INotifyPropertyChanged
{
	public int TestValue
	{
		get { return testValue; }
		set
		{
			testValue = value;
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs("TestValue"));
		}
	}

	private int testValue;

	public event PropertyChangedEventHandler  PropertyChanged;
} 



Calling SetValue(DependencyProperty) on two-way BindingExpression updates the model and keeps the expression. Calling it on one-way binding expression replaces the local BindingExpression value with the specified value and it's no longer bound.

I guess if you want to keep the one-way mode, you could rebind again from NodeModified handler.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint