用户在WPF中保存可自定义模板
本文关键字:自定义 保存 WPF 用户 | 更新日期: 2023-09-27 18:28:26
我有一个WPF-xaml模板和与各种控件相关的代码。用户可以四处移动这些控件,从而获得所需的布局。但是,一旦用户重新启动程序,控件就会返回到其原始位置。我如何制作它以便用户可以保存布局?
您可以保存、重新加载布局(xaml
):
-
用户更改布局[在
Window Closing
事件上]后,您可以使用XamlWriter
静态类保存XAML文件库更改后的布局。事实上,您序列化了容器控件并将其保存在一个文件中。 -
此外,您还需要一些代码[在
InitializeComponent()
]之后的窗口构造函数中]来从文件中重新加载容器控件[及其控件]的序列化布局。
我放了一个样本(由Matt Searles撰写),在这里:
<StackPanel>
<WrapPanel x:Name="wrapPanel1" Height="200"></WrapPanel>
<Button Click="AddButton">Add Button</Button>
<Button Click="SaveButtons">Save Buttons</Button>
<Button Click="ReloadButtons">Reload Buttons</Button>
</StackPanel>
代码背后:
/// <summary>
/// Add a button to wrapPanel1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AddButton(object sender, RoutedEventArgs e)
{
// Create the Button.
Button button = new Button();
button.Height = 50;
button.Width = 100;
button.Background = Brushes.AliceBlue;
button.Content = "Click Me";
wrapPanel1.Children.Add(button);
}
/// <summary>
/// Save wrapPanel1 to AA.xaml
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveButtons(object sender, RoutedEventArgs e)
{
StringBuilder outstr = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
settings.NewLineOnAttributes = true;
XamlDesignerSerializationManager dsm = new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings));
dsm.XamlWriterMode = XamlWriterMode.Expression;
XamlWriter.Save(wrapPanel1, dsm);
string savedControls = outstr.ToString();
File.WriteAllText(@"AA.xaml", savedControls);
}
/// <summary>
/// Reload the buttons in AA.xaml
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ReloadButtons(object sender, RoutedEventArgs e)
{
StreamReader sR = new StreamReader(@"AA.xaml");
string text = sR.ReadToEnd();
sR.Close();
StringReader stringReader = new StringReader(text);
XmlReader xmlReader = XmlReader.Create(stringReader);
WrapPanel wp = (WrapPanel)System.Windows.Markup.XamlReader.Load(xmlReader);
wrapPanel1.Children.Clear(); // clear the existing children
foreach (FrameworkElement child in wp.Children) // and for each child in the WrapPanel we just loaded (wp)
{
wrapPanel1.Children.Add(CloneFrameworkElement(child)); // clone the child and add it to our existing wrap panel
}
}
/// <summary>
/// Clone a framework element by serializing and deserializing it
/// </summary>
/// <param name="originalElement"></param>
/// <returns></returns>
FrameworkElement CloneFrameworkElement(FrameworkElement originalElement)
{
string elementString = XamlWriter.Save(originalElement);
StringReader stringReader = new StringReader(elementString);
XmlReader xmlReader = XmlReader.Create(stringReader);
FrameworkElement clonedElement = (FrameworkElement)XamlReader.Load(xmlReader);
return clonedElement;
}