2015-03-11 4 views
0

Я пытаюсь ссылаться на LinearGradientBrush с XAML анализатором, но он не может идентифицировать объект, и я получаю исключение:Как использовать встроенный XAML в C# легко создавать собственные объекты в коде-за

«Невозможно создать неизвестный тип« LinearGradientBrush »«

Возможно ли, чтобы этот тип был распознан во время выполнения?

Вот код, я использую:

public static class CustomBrushes 
{ 
    public static Brush LinGrad_Bevel() 
    { 


     StringReader sr = new StringReader(@"<LinearGradientBrush EndPoint='0.5,1' MappingMode='RelativeToBoundingBox' StartPoint='0.5,0'> 
       <GradientStop Color='#00F7F7F7' Offset='0'/> 
       <GradientStop Offset='1'/> 
       <GradientStop Color='Black' Offset='0.741'/> 
       <GradientStop Color='Black' Offset='0.75'/> 
       <GradientStop Color='White' Offset='0.25'/> 
      </LinearGradientBrush>"); 
     XmlReader xr = XmlReader.Create(sr); 


     return (Brush)XamlReader.Load(xr); 
    } 
} 

Я действительно не люблю программирует в XAML (особенно потому, что большинство из того, что я делаю, это дизайн зависит от потока выполнения программы, но некоторые объекты просто путь проще прототипа в нем, чем C#, и я бы предпочел использовать этот метод ...

Я читал, что я должен включать такую ​​строку где-то, но, честно говоря, я не понимаю почему и кажется, что это не работает, если я придерживаюсь его под всеми «операциями»

[сборка: XmlnsDefinition («http://schemas.microsoft.com/netfx/2007/xaml/presentation», «System.Windows.Media»)]

В любом случае, любая помощь при анализе времени выполнения XAML в файлах кода C# будет оценена.

+2

SOC (разделение интересов) существует, чтобы сделать! Если вам действительно нужно это сделать, используйте Object из API WPF. – Fals

+0

Весь код для этого UserControl выполняется в коде. Я недостаточно разбираюсь в XAML относительно того, как процедурно делать много изменений в GUI во время выполнения без использования C#, что и делает этот UserControl (много добавлений и вычитаний объектов сетки и их изменение размера и т. Д.), Но я может сделать это на C#. Я просто подумал, что было бы легче создать кисть, как мне это нравится, и проанализировать ее, а не вручную записать ее на C# ... – ThisHandleNotInUse

ответ

3

Чтобы ответить на ваш конкретный вопрос, должны быть предоставлены декларации пространства имен при компиляции XAML. Самый простой способ сделать это - просто вставить их в свою строку. Например:

StringReader sr = new StringReader(@" 
    <LinearGradientBrush 
     xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
     xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" 
     EndPoint='0.5,1' MappingMode='RelativeToBoundingBox' StartPoint='0.5,0'> 
    <GradientStop Color='#00F7F7F7' Offset='0'/> 
    <GradientStop Offset='1'/> 
    <GradientStop Color='Black' Offset='0.741'/> 
    <GradientStop Color='Black' Offset='0.75'/> 
    <GradientStop Color='White' Offset='0.25'/> 
</LinearGradientBrush>"); 
XmlReader xr = XmlReader.Create(sr); 

return (Brush)XamlReader.Load(xr); 

Теперь, что сказал, я бы сказал, что выше, мне кажется, чтобы быть минимум предпочтительный способ пойти об этом. Если вы хотите использовать объект многократного использования Brush, и вы хотите использовать XAML, чтобы объявить его вместо того, чтобы проходить через фактический API-интерфейс WPF, я думаю, что лучший способ сделать это - поместить объявление в одну из соответствующих коллекций Resources в вашу программу.

Например, если вы хотите, чтобы иметь возможность использовать его по всей программе, в ряде различных окон, вы можете сделать его глобальным ресурсом, поместив его в App.xaml файл:

<Application x:Class="TestSO28999367XamlReader.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      StartupUri="MainWindow.xaml"> 
    <Application.Resources> 
    <LinearGradientBrush x:Key="beveledLinearGradientBrush" 
        EndPoint='0.5,1' MappingMode='RelativeToBoundingBox' StartPoint='0.5,0'> 
     <GradientStop Color='#00F7F7F7' Offset='0'/> 
     <GradientStop Offset='1'/> 
     <GradientStop Color='Black' Offset='0.741'/> 
     <GradientStop Color='Black' Offset='0.75'/> 
     <GradientStop Color='White' Offset='0.25'/> 
    </LinearGradientBrush> 
    </Application.Resources> 
</Application> 

If ваше использование будет ограничено только одним объектом Window или даже некоторым подэлементом этого, вы можете добавить объявление в коллекцию Resources для этого объекта вместо того, чтобы помещать его в App.xaml.

Несмотря на это, то вы можете получить доступ к нему с этим выражением:

(Brush)FindResource("beveledLinearGradientBrush") 

Конечно, вы можете сделать ключ для ничего ресурса вы хотите & hellip; он не должен быть beveledLinearGradientBrush.

Вы все еще можете использовать это для инициализации некоторого ресурса с кодом, используя вышеуказанное выражение C# для извлечения объекта. Однако обратите внимание, что когда вы делаете это выше, кисть также становится доступной для прямого использования в любом XAML, посредством выражения "{StaticResource beveledLinearGradientBrush}".

Например:

<Border Background="{StaticResource beveledLinearGradientBrush}"/> 
+0

Это здорово, я признаюсь, что я подумал, может быть, я мог бы просто объявить объекты в ресурсе словарь и по-прежнему получать доступ к ним на C# после того, как я сделал это сообщение, но я не думал об этом раньше. Проблема в том, что мой пользовательский объект управления будет находиться в DLL, поэтому мне не нужно будет делать какие-либо корректировки для приложения для использования пользовательского элемента управления, и я все еще пытаюсь выяснить, как именно XAML может быть включен в DLL – ThisHandleNotInUse

+0

Я новичок в WPF - извините, я так сильно теряю на этом - это вне моего обычного метода мышления относительно написания C# – ThisHandleNotInUse

+0

@ThisHandleNotInUse: ресурсы XAML отлично работают в DLL. Были ли у вас какие-то особые трудности с их использованием? –