This is a migrated thread and some comments may be shown as answers.

Determine if Diagram has changed

6 Answers 126 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
The Cowboy
Top achievements
Rank 1
The Cowboy asked on 04 May 2012, 12:33 PM
What is the best method to determine if a given Diagram has changed (i.e. attributes of a shape changed, new shape, etc.) when not using a diagram bound with GraphSource?

6 Answers, 1 is accepted

Sort by
0
Francois Vanderseypen
Top achievements
Rank 2
answered on 04 May 2012, 01:49 PM
Ultimately the diagram framework should implement an easy to use property which tells you whether the diagram has changed. For now, the best option is to compute a hash of the (saved) diagram. For example, something like the following:

public int ComputeHash(string path) {
  System.Security.Cryptography.HashAlgorithm hashAlgorithm System.Security.Cryptography.HashAlgorithm.Create();
  FileStream fs = new FileStream(path, FileMode.Open);
  byte[] fileHash = hashAlgorithm.ComputeHash(fs);
  fs.Close();
  return BitConverter.ToInt32(fileHash, 0);
}

Hope this helps, Fr.
0
The Cowboy
Top achievements
Rank 1
answered on 05 May 2012, 02:50 PM
Agreed it should be built in to the RadDiagram.

If I want to bind to my own "IsDirty" property (say for a save button), I really need to listen to all the events which would indicate changes to the Diagram... not pretty, but it will work.
0
Francois Vanderseypen
Top achievements
Rank 2
answered on 05 May 2012, 04:42 PM
As I tried to explain, you don't need to listen to all the events. You simply compare the hashes of the two XML files. Use the Save() method, compute the hash and compare with a previous hash value.

Fr.

0
The Cowboy
Top achievements
Rank 1
answered on 07 May 2012, 12:27 PM
I understood your approach, but I guess I should have been a little clearer in what I am aiming for: a dependency property, to which I can bind--say a save button--and know when the RadDiagram is dirty.
0
Accepted
Francois Vanderseypen
Top achievements
Rank 2
answered on 07 May 2012, 01:08 PM
The trick goes as follows;

add the hash computation to your code

public int ComputeHash()
{
    var hashAlgorithm = new SHA512Managed();
 
    var fs = new MemoryStream();
    var xml = diagram.Save();
    new StreamWriter(fs).Write(xml);
    fs.Position = 0;
    var fileHash = hashAlgorithm.ComputeHash(fs);
    fs.Close();
    return BitConverter.ToInt32(fileHash, 0);
}

In the onload event you set

lastTick = DateTime.Now;
this.refHash = this.ComputeHash();
diagram.LayoutUpdated += DiagramOnLayoutUpdated;

and add the handler

private void DiagramOnLayoutUpdated(object sender, EventArgs eventArgs)
{
    var now = DateTime.Now;
    if ((now - lastTick).TotalSeconds > 5)
    {
        var newhash = this.ComputeHash();
        this.SaveEnabled = this.refHash != newhash;
    }
}

This means that the check occurs only if some activity happened on the surface and I added a time window of five seconds since it otherwise overloads things, but you can change this as you wish.

The dependency prop is standard:

public static readonly DependencyProperty SaveEnabledProperty =
    DependencyProperty.Register("SaveEnabled", typeof(bool), typeof(MainWindow),
        new FrameworkPropertyMetadata(false,OnSaveEnabledChanged));
 
      
public bool SaveEnabled
{
    get { return (bool)GetValue(SaveEnabledProperty); }
    set { SetValue(SaveEnabledProperty, value); }
}
 
      
private static void OnSaveEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ((MainWindow)d).OnSaveEnabledChanged(e);
}
 
          
protected virtual void OnSaveEnabledChanged(DependencyPropertyChangedEventArgs e)
{
}

which can be bound to a button

<telerik:RadButton Width="20" Height="50" Content="Save" Margin="5" IsEnabled="{Binding SaveEnabled}" />


This is not the most pleasing way to proceed but I'd hope it helps you out, for now.


Fr.
0
The Cowboy
Top achievements
Rank 1
answered on 07 May 2012, 06:26 PM
Thanks.  This will work, although the LayoutUpdated event is fired quite frequently--even when the mouse is just moving it seems--so, I will have to weigh the performance hit vs. functionality.  I look forward to having solved natively in future releases.
Tags
Diagram
Asked by
The Cowboy
Top achievements
Rank 1
Answers by
Francois Vanderseypen
Top achievements
Rank 2
The Cowboy
Top achievements
Rank 1
Share this question
or