private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (sender == this.MenuItemExit) {
                if (GeometricNetworkViewModel.Default.IsDirty) {
                    MessageBoxResult r = MessageBox.Show(
                        "Do you want to save before closing?",
                        GeometricNetworkViewModel.Default.WindowTitle,
                        MessageBoxButton.YesNoCancel,
                        MessageBoxImage.Exclamation,
                        MessageBoxResult.Yes
                    );
                    switch (r) {
                        case MessageBoxResult.Yes:
                            // Save document
                            GeometricNetworkViewModel.Default.Save();

                            // If user canceled save dialog then exit
                            if (GeometricNetworkViewModel.Default.IsDirty) { return; }

                            break;
                        case MessageBoxResult.No:
                            break;
                        case MessageBoxResult.Cancel:
                        default:
                            return;
                    }
                }

                // Exit application
                Application.Current.Shutdown(0);
            }
            else if (sender == this.ButtonOpen) {
                // Exit if dataset already open
                if (GeometricNetworkViewModel.Default.Dataset != null) {
                    MessageBox.Show(
                        "Please close the document first",
                        GeometricNetworkViewModel.Default.WindowTitle,
                        MessageBoxButton.OK,
                        MessageBoxImage.Information,
                        MessageBoxResult.OK
                    );
                    return;
                }

                OpenFileDialog openFileDialog = new OpenFileDialog() {
                    CheckFileExists = true,
                    Filter = "GN definition document" + " (*.esriGeoNet)|*.esriGeoNet",
                    FilterIndex = 1,
                    Multiselect = false,
                    Title = GeometricNetworkViewModel.Default.WindowTitle
                };

                // Check if user pressed "Save" and File is OK.
                bool? ok = openFileDialog.ShowDialog(this);
                if (!ok.HasValue || !ok.Value) { return; }
                if (string.IsNullOrWhiteSpace(openFileDialog.FileName)) { return; }

                //
                GeometricNetworkViewModel.Default.Load(openFileDialog.FileName);
            }
            else if (sender == this.ButtonSave) {
                // Handle event to prevent bubbling event to ButtonSave
                if (e != null) {
                    e.Handled = true;
                }

                // Exit if no dataset
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }

                // If no document, show "save as" dialog
                if (GeometricNetworkViewModel.Default.Document == null) {
                    this.Button_Click(this.ButtonSaveAs, null);
                    return;
                }

                // Save document
                GeometricNetworkViewModel.Default.Save();
            }
            else if (sender == this.ButtonSaveAs) {
                // Handle event to prevent bubbling event to ButtonSave
                if (e != null) {
                    e.Handled = true;
                }

                // Show save dialog
                SaveFileDialog saveFileDialog = new SaveFileDialog() {
                    DefaultExt = "esriGeoNet",
                    FileName = "Document1",
                    Filter = "GN definition document" + " (*.esriGeoNet)|*.esriGeoNet",
                    FilterIndex = 1,
                    OverwritePrompt = true,
                    RestoreDirectory = false,
                    Title = GeometricNetworkViewModel.Default.WindowTitle
                };

                // Check if user pressed "Save" and File is OK.
                bool? ok = saveFileDialog.ShowDialog(this);
                if (!ok.HasValue || !ok.Value) { return; }
                if (string.IsNullOrWhiteSpace(saveFileDialog.FileName)) { return; }

                //
                GeometricNetworkViewModel.Default.Save(saveFileDialog.FileName);
            }
            else if (sender == this.ButtonClose) {
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }
                if (GeometricNetworkViewModel.Default.IsDirty) {
                    MessageBoxResult r = MessageBox.Show(
                        "Do you want to save before closing?",
                        GeometricNetworkViewModel.Default.WindowTitle,
                        MessageBoxButton.YesNoCancel,
                        MessageBoxImage.Exclamation,
                        MessageBoxResult.Yes
                    );
                    switch (r) {
                        case MessageBoxResult.Yes:
                            GeometricNetworkViewModel.Default.Save();
                            break;
                        case MessageBoxResult.No:
                            break;
                        case MessageBoxResult.Cancel:
                        default:
                            return;
                    }
                }

                // Clear current dataset
                GeometricNetworkViewModel.Default.Clear();
            }
            else if (sender == this.ButtonImport) {
                // Create GxObjectFilter for GxDialog
                IGxObjectFilter gxObjectFilter = new GxFilterGeometricNetworksClass();

                // Create GxDialog
                IGxDialog gxDialog = new GxDialogClass() {
                    AllowMultiSelect = false,
                    ButtonCaption = "Import",
                    ObjectFilter = gxObjectFilter,
                    RememberLocation = true,
                    Title = "Please select a geometric network"
                };

                // Declare Enumerator to hold selected objects
                IEnumGxObject enumGxObject = null;

                // Open Dialog
                if (!gxDialog.DoModalOpen(0, out enumGxObject)) { return; }
                if (enumGxObject == null) { return; }

                // Get Selected Object (if any)
                IGxObject gxObject = enumGxObject.Next();
                if (gxObject == null) { return; }
                if (!gxObject.IsValid) { return; }

                // Get GxDataset
                if (!(gxObject is IGxDataset)) { return; }
                IGxDataset gxDataset = (IGxDataset)gxObject;

                // Load geometric network from named object
                IName name = (IName)gxDataset.DatasetName;
                GeometricNetworkLoader loader = new GeometricNetworkLoader(name);
                loader.Load();
            }
            else if (sender == this.ButtonExport) {
                ResultType ok = this.ExportGeometricNetwork();
                switch (ok) {
                    case ResultType.Cancelled:
                        break;
                    case ResultType.Error:
                        MessageBox.Show(
                            "Geometric network creation failed",
                            GeometricNetworkViewModel.Default.WindowTitle,
                            MessageBoxButton.OK,
                            MessageBoxImage.Information,
                            MessageBoxResult.OK
                        );
                        break;
                    case ResultType.Successful:
                        MessageBox.Show(
                           "Geometric network creation successful",
                           GeometricNetworkViewModel.Default.WindowTitle,
                           MessageBoxButton.OK,
                           MessageBoxImage.Information,
                           MessageBoxResult.OK
                       );
                        break;
                }
            }
            else if (sender == this.ButtonOutput) {
                if (this.DockableContentOutput.IsHidden) {
                    this.DockableContentOutput.Show();
                }
                else if (this.DockableContentOutput.IsAutoHidden) {
                    this.DockableContentOutput.ToggleAutoHide();
                }
            }
            else if (sender == this.ButtonJunctionAdd) {
                // Exit if invalid
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }
                if (GeometricNetworkViewModel.Default.SelectedJunctionRule != null) { return; }

                // Add junction rule
                if (this.DataGridJunctionRules.SelectedCells == null) { return; }
                if (this.DataGridJunctionRules.SelectedCells.Count == 0) { return; }
                DataGridCellInfo ci = this.DataGridJunctionRules.SelectedCells[0];
                object o = ci.Item;
                if (o == null) { return; }

                RuleDataGridColumn rdgc = ci.Column as RuleDataGridColumn;
                if (rdgc == null) { return; }

                ZGeometricNetwork zgn = GeometricNetworkViewModel.Default.Dataset as ZGeometricNetwork;
                if (zgn == null) { return; }

                // Create new rule
                ZSubtype e1 = o.GetType().GetProperty(RuleMatrix.EDGE_SUBTYPE).GetValue(o, null) as ZSubtype;
                ZSubtype j1 = zgn.FindSubtype(rdgc.ColumnName);
                ZJunctionConnectivityRule rule = new ZJunctionConnectivityRule(e1, j1);

                // Add rule to network
                zgn.JunctionRules.Add(rule);

                // Update data source
                o.GetType().GetProperty(rdgc.ColumnName).SetValue(o, rule, null);

                // Refresh display
                GeometricNetworkViewModel.Default.SelectedJunctionRule = (ZJunctionConnectivityRule)rule;
                GeometricNetworkViewModel.Default.JunctionRuleDataSource.Refresh();

                // Focus cell
                DataGridCellInfo cell = new DataGridCellInfo(o, rdgc);
                this.DataGridJunctionRules.CurrentCell = cell;
                this.DataGridJunctionRules.SelectedCells.Clear();
                this.DataGridJunctionRules.SelectedCells.Add(cell);

                // Make document dirty
                GeometricNetworkViewModel.Default.MakeDirty();
            }
            else if (sender == this.ButtonJunctionRemove) {
                // Exit if invalid
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }
                if (GeometricNetworkViewModel.Default.SelectedJunctionRule == null) { return; }

                // Get selected cell
                if (this.DataGridJunctionRules.SelectedCells == null) { return; }
                if (this.DataGridJunctionRules.SelectedCells.Count == 0) { return; }
                DataGridCellInfo ci = this.DataGridJunctionRules.SelectedCells[0];
                object o = ci.Item;
                if (o == null) { return; }

                // Get selected rule
                RuleDataGridColumn rdgc = ci.Column as RuleDataGridColumn;
                if (rdgc == null) { return; }
                ZRule rule = o.GetType().GetProperty(rdgc.ColumnName).GetValue(o, null) as ZRule;
                if (rule == null) { return; }

                // Update data source
                o.GetType().GetProperty(rdgc.ColumnName).SetValue(o, null, null);

                // Remove from dataset
                ZGeometricNetwork zgn = GeometricNetworkViewModel.Default.Dataset as ZGeometricNetwork;
                if (zgn == null) { return; }
                zgn.JunctionRules.Remove(rule);

                // Refresh display
                GeometricNetworkViewModel.Default.SelectedJunctionRule = (ZJunctionConnectivityRule)rule;
                GeometricNetworkViewModel.Default.JunctionRuleDataSource.Refresh();

                // Focus cell
                DataGridCellInfo cell = new DataGridCellInfo(o, rdgc);
                this.DataGridJunctionRules.CurrentCell = cell;
                this.DataGridJunctionRules.SelectedCells.Clear();
                this.DataGridJunctionRules.SelectedCells.Add(cell);

                // Make document dirty
                GeometricNetworkViewModel.Default.MakeDirty();
            }
        }
        private void Window_Drop(object sender, DragEventArgs e)
        {
            try {
                // Handle event
                e.Handled = true;

                DataObject d = e.Data as DataObject;

                if (d.GetDataPresent(DataFormats.FileDrop)) {
                    if (d.ContainsFileDropList()) {
                        StringCollection sc = d.GetFileDropList();
                        string file = sc[0];
                        GeometricNetworkViewModel.Default.Load(file);
                        GeometricNetworkViewModel.Default.CreateRuleDataSource();
                        GeometricNetworkViewModel.Default.Document = file;
                    }
                }
                else if (d.GetDataPresent(GeometricNetworkWindow.DATAOBJECT_ESRINAMES)) {
                    // Get Dropped Object
                    object objectDrop = d.GetData(GeometricNetworkWindow.DATAOBJECT_ESRINAMES);
                    MemoryStream memoryStream = (MemoryStream)objectDrop;
                    byte[] bytes = memoryStream.ToArray();
                    memoryStream.Close();

                    // Create loader
                    GeometricNetworkLoader loader = new GeometricNetworkLoader(bytes);
                    loader.Load();
                }
            }
            catch (Exception ex) {
            #if DEBUG
                MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
            #endif
            }
        }