我想通過反射加載自定義控制庫在Windows 8 Metro C#應用程序,該庫被加載,但generic.xaml中指定的樣式不加載,最終我試圖加載generic.xaml通過使它作爲嵌入式資源,然後提取Generic.xaml到某個位置,作爲一個資源字典對象的URI指定它的位置,但它拋出一個錯誤Windows應用商店應用:通過反射從自定義控件類庫加載樣式,不調用OnApplyTemplate?
"Failed to create a 'System.Type' from the text local:CustomControl1"
我不能因爲不幸的是創建一個NuGet包或擴展的SDK,是不是我的要求, 下面的示例代碼我寫了複製generic.xaml並將其加載到資源字典中
public sealed class CustomControl1 : Control
{
public CustomControl1()
{
this.DefaultStyleKey = typeof(CustomControl1);
Assembly CurrentAssembly = typeof(CustomControl1).GetTypeInfo().Assembly;
var names = CurrentAssembly.GetManifestResourceNames();
var stream = CurrentAssembly.GetManifestResourceStream(names.First());
//generic.xaml is an embedded resource in the current assembly
if (stream != null)
{
//created new generic.xaml here
var file = ApplicationData.Current.LocalFolder.CreateFileAsync("Generic.xaml", CreationCollisionOption.ReplaceExisting).Completed = (o, a) =>
{
var storageFile = o.GetResults();
var s = storageFile.OpenStreamForWriteAsync().Result;
var length = (int)stream.Length;
byte[] bytes = new byte[length];
int output = stream.Read(bytes, 0, length);
s.Write(bytes, 0, length);
s.Flush();
s.Dispose();
var asyncResult = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,() =>
{
var resourceDict = new ResourceDictionary();
var uri = new Uri("ms-appdata:///local/" + storageFile.Name);
resourceDict.Source = uri;
});
};
}
}
// OnApplyTemplate is not called without loading the style from generic.xaml
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
}
下面的代碼我在自定義控制庫的構造函數中寫道,使控制模板可以不generic.xaml
在這裏,因爲屬性TargeType =設置「本地:CustomControl1」不存在控制被加載正確的,在這裏,因爲我在構造函數中加載的風格,OnApplyTemplate被調用
StringBuilder sb = new StringBuilder();
sb.Append(@"<ControlTemplate
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:d=""http://schemas.microsoft.com/expression/blend/2008""
xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"">");
sb.Append(@"<Border Background=""{TemplateBinding
Background}""
BorderBrush=""{TemplateBinding BorderBrush}""
BorderThickness=""{TemplateBinding BorderThickness}"">
<Grid>
<Button x:Name=""Tbx1"" Content=""Hello World"" Foreground=""HotPink""
HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch""/>
</Grid>
</Border>");
sb.Append(@"</ControlTemplate>");
this.Template = (ControlTemplate)XamlReader.Load(sb.ToString());
但問題是加載使用XamlReader是不是一個好主意,除非我們進行選擇的所有樣式。因爲可能有各種各樣的依賴樣式也必須加載。
我注意到你正在創建一個'ResourceDictionary',但似乎沒有在任何地方使用它。在我看來,在你加載樣式的位置(並且出錯),你沒有正確定義'local'命名空間。我仍然不確定爲什麼你需要像這樣加載控件。這樣做是否符合您的要求?或者你可以改變更類似於我發佈的答案嗎? –
嗨Nate,感謝您的回覆, –
我的資源字典的一部分顯示在下面 –