Приложения для Магазина Windows: загружая стили из библиотеки классов customcontrol с помощью отражения, OnApplyTemplate не вызывается?
Я пытаюсь загрузить пользовательскую библиотеку элементов управления с помощью отражения в Windows 8 Metro C# App, библиотека загружена, но стили, указанные в generic.xaml, не загружены, в конце концов я попытался загрузить generic.xaml, сделав его встроенным ресурсом. и затем извлек Generic.xaml в местоположение и указал его местоположение как URI объекта ResourceDictionary, но он выдает ошибку
"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="local: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 не очень хорошая идея, если только у нас нет параметров. Так как могут быть различные зависимые стили, которые тоже должны быть загружены.
1 ответ
Проверьте, как они это делают в WinRTXamlToolkit. Они создают Generic.xaml
для проекта и включить все шаблоны управления внутри отдельных стилей в разных ResourceDictionary
s упакованы рядом с соответствующими элементами управления.
Проще говоря (для шаблонных элементов управления, которые вы используете):
Сделайте два файла для каждого элемента управления,
MyControl.cs
а такжеMyControl.xaml
В
MyControl.cs
в вашемMyControl
конструктор, установитеStyleKey
бытьtypeof(MyControl)
(как вы делаете в настоящее время).Убедитесь, что есть стиль для вашего контроля с
TargetType
установить тип вашего контроля. Сделайте то же самое дляControlTemplate
что у вас есть какTemplate
свойство установлено вStyle
,В
MyControl.xaml
, делатьResourceDictionary
который хранит все необходимые стили, шаблоны и ресурсы.В вашем
Generic.xaml
, создатьMergedDictionaries
пометить под корнем и создатьResourceDictionary
для каждого элемента управления задайте для источника полный путьMyControl.xaml
Установите для каждого из файлов.xaml тип сборки Page
с CustomTool
установлен в MSBuild:Compile
,
Надеюсь, это поможет и счастливого кодирования!