public ZGeometricNetwork(IGeometricNetwork geometricNetwork)
            : base(geometricNetwork as IDataset)
        {
            // Initialize collections
            this.NetworkClasses = new ObservableCollection<ZNetworkClass>();
            this.Weights = new ObservableCollection<ZNetWeight>();
            this.EdgeRules = new ObservableCollection<ZRule>();
            this.JunctionRules = new ObservableCollection<ZRule>();

            // Report addition
            GeometricNetworkViewModel.Default.AddMessage(string.Format("Finding network classes..."), MessageType.Information);

            // Add network classes
            IEnumFeatureClass enumFeatureClass1 = geometricNetwork.get_ClassesByType(esriFeatureType.esriFTSimpleJunction);
            IEnumFeatureClass enumFeatureClass2 = geometricNetwork.get_ClassesByType(esriFeatureType.esriFTSimpleEdge);
            IEnumFeatureClass enumFeatureClass3 = geometricNetwork.get_ClassesByType(esriFeatureType.esriFTComplexEdge);
            foreach (IEnumFeatureClass enumFeatureClass in new IEnumFeatureClass[] { enumFeatureClass1, enumFeatureClass2, enumFeatureClass3 }) {
                IFeatureClass featureClass = enumFeatureClass.Next();
                while (featureClass != null) {
                    INetworkClass networkClass = featureClass as INetworkClass;
                    if (networkClass != null) {
                        // Create network class
                        ZNetworkClass znc = new ZNetworkClass(networkClass);

                        // Add class to collection
                        this.NetworkClasses.Add(znc);

                        // Report addition
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding class: {0}", znc.Path.Table), MessageType.Information);
                    }
                    featureClass = enumFeatureClass.Next();
                }
            }

            // Add weights and weight associations
            INetwork network = geometricNetwork.Network;
            INetSchema netSchema = (INetSchema)network;
            for (int i = 0; i < netSchema.WeightCount; i++) {
                // Create network weight
                INetWeight netWeight = netSchema.get_Weight(i);
                IEnumNetWeightAssociation enumNetWeightAssocation = netSchema.get_WeightAssociations(i);
                ZNetWeight znw = new ZNetWeight(this, netWeight, enumNetWeightAssocation);

                // Add weight to collection
                this.Weights.Add(znw);

                // Report addition
                GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding weight: {0}", znw.Name), MessageType.Information);
            }

            // Add connectivity rules
            IEnumRule rules = geometricNetwork.Rules;
            IRule rule = rules.Next();
            while (rule != null) {
                if (rule is IJunctionConnectivityRule) {
                    // Create junction rule
                    IJunctionConnectivityRule junctionConnectivityRule = (IJunctionConnectivityRule)rule;
                    ZJunctionConnectivityRule jcr = new ZJunctionConnectivityRule(this, junctionConnectivityRule);

                    // Add junction rule
                    this.JunctionRules.Add(jcr);

                    // Report
                    GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding junction rule: {0}", jcr.Id), MessageType.Information);
                }
                else if (rule is IEdgeConnectivityRule) {
                    // Create edge rule
                    IEdgeConnectivityRule edgeConnectivityRule = (IEdgeConnectivityRule)rule;
                    ZEdgeConnectivityRule ecr = new ZEdgeConnectivityRule(this, edgeConnectivityRule);

                    // Add edge rule
                    this.EdgeRules.Add(ecr);

                    // Report
                    GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding edge rule: {0}", ecr.Id), MessageType.Information);
                }

                rule = rules.Next();
            }
        }
        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();
            }
        }