private void UnregisterHandlers() { foreach (Host host in hosts) { UnregisterHostHandlers(host); } if (xenObject != null) { Pool pool = xenObject as Pool; if (pool != null) { pool.Connection.Cache.DeregisterCollectionChanged <Host>(Host_CollectionChangedWithInvoke); } xenObject.Connection.XenObjectsUpdated -= XenObjectsUpdated; foreach (VM vm in xenObject.Connection.Cache.VMs) { UnregisterVMHandlers(vm); } } foreach (VM vm in vms) { UnregisterVMHandlers(vm); // Should duplicate above line, but let's be safe } foreach (Control c in pageContainerPanel.Controls) { VMMemoryRow vmRow = c as VMMemoryRow; if (vmRow != null) { vmRow.UnregisterHandlers(); continue; } HostMemoryRow hostRow = c as HostMemoryRow; if (hostRow != null) { hostRow.UnregisterHandlers(); } } }
private void Rebuild() { Program.AssertOnEventThread(); _rebuild_needed = false; if (!this.Visible) { return; } _rebuilding = true; pageContainerPanel.SuspendLayout(); // Store a list of the current controls. We remove them at the end because it makes less flicker that way. // While we're going through them, remember which VMs were on expanded rows. List <Control> oldControls = new List <Control>(pageContainerPanel.Controls.Count); List <VM> expandedVMs = new List <VM>(vms.Count); foreach (Control c in pageContainerPanel.Controls) { oldControls.Add(c); VMMemoryRow vmRow = c as VMMemoryRow; if (vmRow != null && vmRow.Expanded) { expandedVMs.AddRange(vmRow.VMs); } } // Group VMs with the same settings Dictionary <MemSettings, List <VM> > settingsToVMs = new Dictionary <MemSettings, List <VM> >(); // all VMs with a particular setting List <MemSettings> listSettings = new List <MemSettings>(); // also make a list of MemSettings to preserve the order vms.Sort(); foreach (VM vm in vms) { MemSettings settings = vm.has_ballooning() ? new MemSettings(true, vm.power_state, vm.memory_static_min, vm.memory_static_max, vm.memory_dynamic_min, vm.memory_dynamic_max) : new MemSettings(false, vm.power_state, 0, vm.memory_static_max, 0, 0); // don't consider other mem settings if ballooning off if (!settingsToVMs.ContainsKey(settings)) // we've not seen these settings on another VM { settingsToVMs.Add(settings, new List <VM>()); listSettings.Add(settings); } settingsToVMs[settings].Add(vm); } // Add server rows int initScroll = pageContainerPanel.VerticalScroll.Value; int top = pageContainerPanel.Padding.Top - initScroll; hosts.Sort(); foreach (Host host in hosts) { Host_metrics metrics = host.Connection.Resolve(host.metrics); if (metrics == null || !metrics.live) { continue; } AddRowToPanel(new HostMemoryRow(host), ref top); } // Add VM rows. // Sort the rows first by power state then by usual sort order of first VM (because of vms.Sort() above). // Easier to traverse listSettings five times, but more complicated sorts could be achieved by listSettings.Sort(). vm_power_state[] power_state_order = { vm_power_state.Running, vm_power_state.Paused, vm_power_state.Suspended, vm_power_state.Halted, vm_power_state.unknown }; foreach (vm_power_state ps in power_state_order) { foreach (MemSettings settings in listSettings) { if (settings.power_state == ps) { List <VM> rowVMs = settingsToVMs[settings]; bool expand = Helpers.ListsIntersect(expandedVMs, rowVMs); // expand header if any of its VMs were expanded before AddRowToPanel(new VMMemoryRow(rowVMs, expand), ref top); } } } // Remove old controls foreach (Control c in oldControls) { pageContainerPanel.Controls.Remove(c); int scroll = initScroll; if (scroll > pageContainerPanel.VerticalScroll.Maximum) { scroll = pageContainerPanel.VerticalScroll.Maximum; } pageContainerPanel.VerticalScroll.Value = scroll; // Without this, the scroll bar can jump around while the page is being rebuilt c.Dispose(); } _rebuilding = false; pageContainerPanel.ResumeLayout(); ReLayout(); SetupDeprecationBanner(); }