[英]WPF MVVM Managing multiple windows
Looking to write a note application in WPF/C# MVVM, not because we need another one but because it'll help me go over a few things I'm trying to become more familiar with. 想要在WPF / C#MVVM中编写笔记应用程序,不是因为我们需要另一个,而是因为它可以帮助我完成一些我想变得更加熟悉的事情。 My question is regarding some guidance on how to handle multiple windows.
我的问题是关于如何处理多个窗口的一些指导。 For example there will be multiple notes not tied to a main window.
例如,将有多个注释未绑定到主窗口。 I'd like to keep track of all open windows, for example if one received focus, I may want to bring the other note windows to the front, but not remove focus from the one I selected, not looking for anyone to give me the code, just some guidance on how to handle it.
我想跟踪所有打开的窗口,例如,如果一个窗口获得焦点,我可能希望将其他笔记窗口置于最前面,但不要将焦点从我选择的窗口中移开,而不是寻找任何人来给我代码,只是一些有关如何处理它的指导。
Maybe this can help you in some way: http://kentb.blogspot.nl/2011/11/application-im-currently-working-on-top.html 也许这可以在某种程度上帮助您: http : //kentb.blogspot.nl/2011/11/application-im-currently-working-on-top.html
The important parts from the article: 文章中的重要部分:
What I did instead was had the WindowItemsControl create WindowItemsControlItem instances as containers.
相反,我所做的是让WindowItemsControl创建WindowItemsControlItem实例作为容器。 These containers are really just surrogates for the Window they represent.
这些容器实际上只是它们所代表的窗口的替代。 When they're initialized, they display the Window.
初始化后,它们将显示窗口。 When they're destroyed, they close the Window.
当它们被销毁时,它们会关闭窗户。 In addition, if a Window is closed ahead of time, the corresponding data item is removed from the underlying collection and thus too the surrogate from the visual tree.
另外,如果提前关闭Window,则相应的数据项将从基础集合中删除,因此也从可视树中替代。
public class WindowItemsControl : ItemsControl
{
public static readonly DependencyProperty ShowDialogProperty = DependencyProperty.Register(
"ShowDialog",
typeof(bool),
typeof(WindowItemsControl));
public static readonly DependencyProperty OwnerProperty = DependencyProperty.Register(
"Owner",
typeof(Window),
typeof(WindowItemsControl),
new FrameworkPropertyMetadata(OnOwnerChanged));
public static readonly DependencyProperty WindowStartupLocationProperty = DependencyProperty.Register(
"WindowStartupLocation",
typeof(WindowStartupLocation),
typeof(WindowItemsControl));
public static readonly DependencyProperty RemoveDataItemWhenWindowClosedProperty = DependencyProperty.Register(
"RemoveDataItemWhenWindowClosed",
typeof(bool),
typeof(WindowItemsControl),
new FrameworkPropertyMetadata(true));
static WindowItemsControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowItemsControl), new FrameworkPropertyMetadata(typeof(WindowItemsControl)));
}
public bool ShowDialog
{
get { return (bool)this.GetValue(ShowDialogProperty); }
set { this.SetValue(ShowDialogProperty, value); }
}
public Window Owner
{
get { return this.GetValue(OwnerProperty) as Window; }
set { this.SetValue(OwnerProperty, value); }
}
public WindowStartupLocation WindowStartupLocation
{
get { return (WindowStartupLocation)this.GetValue(WindowStartupLocationProperty); }
set { this.SetValue(WindowStartupLocationProperty, value); }
}
public bool RemoveDataItemWhenWindowClosed
{
get { return (bool)this.GetValue(RemoveDataItemWhenWindowClosedProperty); }
set { this.SetValue(RemoveDataItemWhenWindowClosedProperty, value); }
}
protected override DependencyObject GetContainerForItemOverride()
{
return new WindowItemsControlItem(this);
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is WindowItemsControlItem;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
(element as WindowItemsControlItem).Window.Content = item;
}
protected override bool ShouldApplyItemContainerStyle(DependencyObject container, object item)
{
// the item container style will be applied to the windows, not to the containers (which are surrogates for the window)
return false;
}
private static void OnOwnerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var windowItemsControl = (WindowItemsControl)dependencyObject;
var owner = (Window)e.NewValue;
for (var i = 0; i < windowItemsControl.Items.Count; ++i)
{
var container = windowItemsControl.ItemContainerGenerator.ContainerFromIndex(i) as WindowItemsControlItem;
if (container == null)
{
continue;
}
container.Window.Owner = owner;
}
}
}
public class WindowItemsControlItem : FrameworkElement
{
private readonly WindowItemsControl windowItemsControl;
private readonly Window window;
static WindowItemsControlItem()
{
// there is no need for these items to be visible as they are simply surrogates for the windows that they display
VisibilityProperty.OverrideMetadata(typeof(WindowItemsControlItem), new FrameworkPropertyMetadata(Visibility.Collapsed));
}
public WindowItemsControlItem(WindowItemsControl windowItemsControl)
{
windowItemsControl.AssertNotNull("windowItemsControl");
this.windowItemsControl = windowItemsControl;
this.window = this.CreateWindow(windowItemsControl);
this.Loaded += delegate
{
if (this.windowItemsControl.ShowDialog)
{
this.window.ShowDialog();
}
else
{
this.window.Show();
}
};
this.Unloaded += delegate
{
this.window.Close();
};
}
public Window Window
{
get { return this.window; }
}
private Window CreateWindow(WindowItemsControl windowItemsControl)
{
var window = new Window
{
Owner = windowItemsControl.Owner,
WindowStartupLocation = windowItemsControl.WindowStartupLocation
};
BindingOperations.SetBinding(window, Window.DataContextProperty, new Binding("Content") { Source = window });
BindingOperations.SetBinding(window, Window.StyleProperty, new Binding("ItemContainerStyle") { Source = windowItemsControl });
BindingOperations.SetBinding(window, Window.ContentTemplateProperty, new Binding("ItemTemplate") { Source = windowItemsControl });
BindingOperations.SetBinding(window, Window.ContentTemplateSelectorProperty, new Binding("ItemTemplateSelector") { Source = windowItemsControl });
window.Closed += delegate
{
// orphan the content because it might be hosted somewhere else later (including in another window)
window.Content = null;
// if the window closes, attempt to remove the original item from the underlying collection, which will result in this surrogate being removed too
if (windowItemsControl.RemoveDataItemWhenWindowClosed)
{
var editableItems = windowItemsControl.Items as IEditableCollectionView;
if (editableItems != null && editableItems.CanRemove)
{
editableItems.Remove(this.DataContext);
}
}
};
return window;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.