首先讓我們創建一個AttachedProperty使加載的XAML可以添加到任何我們想要的面板或ContentControl中。
public class MyFrameworkObject : DependencyObject
{
public static readonly DependencyProperty RuntimeFrameWorkElementProperty = DependencyProperty.RegisterAttached("RuntimeFrameWorkElement", typeof(FrameworkElement), typeof(MyFrameworkObject),new PropertyMetadata(new PropertyChangedCallback(OnPropertyChanged)));
static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SetRuntimeFrameWorkElement(d as UIElement, e.NewValue as FrameworkElement);
}
public static void SetRuntimeFrameWorkElement(UIElement element, FrameworkElement value)
{
if (element!=null && value != null && value.Parent == null) //The loaded Control can be added to only one Control because its Parent will be set
{
var panel = element as Panel;
if (panel != null)
{
panel.Children.Add(value);
return;
}
var contentControl = element as ContentControl;
if (contentControl != null)
contentControl.Content = value;
//TODO:ItemsControl
}
}
}
視圖模型:在視圖模型允許創建和負載可能被綁定到上述附加屬性的屬性。
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
LoadXaml();
}
FrameworkElement frameWorkElement;
public FrameworkElement RuntimeFrameWorkElement
{
get { return frameWorkElement; }
set { frameWorkElement = value; OnPropertyChanged("RuntimeFrameWorkElement"); }
}
public void LoadXaml()
{
FileInfo f = new FileInfo(@"F:\myxaml.txt"); //Load xaml from some external file
if (f.Exists)
using (var stream = f.OpenRead())
{
this.RuntimeFrameWorkElement = XamlReader.Load(stream) as FrameworkElement;
}
}
void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
xaml.cs
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
XAML可以使用attachedProperty
<Window x:Class="StackoverflowQues.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StackoverflowQues"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Content="Ok"/>
<Grid local:MyFrameworkObject.RuntimeFrameWorkElement="{Binding RuntimeFrameWorkElement}"></Grid>
</StackPanel>
Simillarly可以綁定這個attachedproperty像棧,碼頭,收任何小組,電網
<StackPanel local:MyFrameworkObject.RuntimeFrameWorkElement="{Binding RuntimeFrameWorkElement}">
</StackPanel>
或者也可以綁定到ContentControl中或ItemsControl的(尚未這樣做)
輸出我已經使用相同的xaml作爲你的
注意:如果您將此附加屬性指定給兩個或更多面板或控件,它將僅添加到第一個面板或控件。因爲那麼加載的xaml控件的Parent將被設置,並且不會添加另一個控件。
http://stackoverflow.com/questions/9021677/loading-xaml-at-runtime-using-the-mvvm-pattern-in-wpf – Donal 2014-09-02 15:57:16