2009-11-07 1 views
0

я пытался создать свой собственный класс Border, а затем вставьте его в моем управлении, но тогда, кажется, я не могу присвоить имена все внутри границ:Создайте такие же границы типа вокруг все мои управления

.. 
<my:ElementBorder> 
     <StackPanel Name="ifBlock" Background="#E0E8FF" /> 
</my:ElementBorder> 
.. 

Как может Я обойду это? Могу ли я использовать шаблоны для чего-то?

EDIT: Извините, что я не понял. Да я подклассы Границу с моим собственным файлом XAML и получил эту ошибку компилятора с кодом выше:

Ошибка 2 Не удается установить атрибут Name значение «ifBlock» на элементе 'StackPanel. «StackPanel» находится под объемом элемента «ElementBorder», , у которого уже было зарегистрировано имя , когда оно было определено в другой области.

Содержание моего класса ElementBorder не очень интересно, но я выложу его в любом случае:

<Border x:Class="DVPE.ElementBorder" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    BorderThickness="4" 
    CornerRadius="4"> 
</Border> 
+0

Подробнее пожалуйста. Вы подклассифицировали Border или катили свой собственный? Является ли ошибка во время компиляции или времени выполнения? Выполняется ли компиляция/запуск, если вы на самом деле не пытаетесь использовать * имя? –

ответ

3

Вводя код, за вами создали дополнительный NameScope. Вы можете удалить эту дополнительную NameScope во время выполнения очистки NameScope после вызова InitializeComponent():

public ElementBorder() 
{ 
    InitializeComponent(); 
    NameScope.SetNameScope(this, null); 
    ... 
} 

Хотя это будет работать, это не лучшее решение. Вам было бы лучше создать стиль, который будет использовать UserControl.

Существует два способа сделать это: с подклассом и без него.

С подкласса

Создать свой ElementBorder подкласс и переопределить стиль по умолчанию.Не называйте InitializeComponent():

public class ElementBorder 
{ 
    static ElementBorder 
    { 
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ElementBorder), new FrameworkPropertyMetadata(typeof(ElementBorer))); 
    } 
    // any additional implementation 
} 

В файле XAML, вместо того, чтобы в том числе тег, создать ResourceDictionary, содержащий стиль с настройками вы хотите:

<ResourceDictionary xmlns=... > 

    <Style TargeType="{x:Type my:ElementBorder}"> 
    <Setter Property="BorderThickness" Value="4" /> 
    ... 

Merge это ResourceDictionary в одном определенную в app.xaml или themes/Generic.xaml с помощью значка MergeDictionary <

Обратите внимание, что вы можете просто поместить стиль в ResourceDictionary в свой app.xaml вместо создания отдельного файла.

Используя это идентично с помощью оригинального ElementBorder:

<my:ElementBorder> 
    <StackPanel ... 

Без подкласса

Это требует меньше кода. Просто поместите стиль в ResourceDictionary, как и раньше, за исключением дать ему топор: Ключ и использовать границы, как это целевой тип:

<ResourceDictionary> 

    <Style x:Key="ElementBorderStyle" TargeType="{x:Type Border}"> 
    <Setter Property="BorderThickness" Value="4" /> 
    ... 

Это может быть использовано следующим образом:

<Border Style="{StaticResource ElementBorderStyle}"> 
    <StackPanel ... 

Если вы хотите, чтобы все ваши границы, чтобы иметь новый стиль, это еще проще. Просто опускаем х: Key и использовать границу в качестве TargetType:

<ResourceDictionary> 

    <Style TargeType="{x:Type Border}"> 
    <Setter Property="BorderThickness" Value="4" /> 
    ... 

Это приведет все границы, чтобы получить стиль, так что вы можете просто написать:

<Border> 
    <StackPanel ... 

Ответ на дополнительный вопрос, заданный в комментарий ниже

Чтобы установить BorderBrush такой же, как фон:

<Style TargeType="{x:Type Border}"> 
    <Setter Property="BorderBrush" Value="{Binding Background, RelativeSource={RelativeSource Self}}" /> 
    ... 

Чтобы установить фон ребенка на фон границы: обычно не требуется, так как до тех пор, пока цвет фона ребенка не установлен, цвет фона границы будет отображаться. Единственное исключение - в ситуациях с отрицательным маржином или RenderTransform, где ребенок не отображает полностью внутри границы. В этом случае вам необходимо привязать фоновое изображение ребенка к фону границы. Это невозможно сделать в стиле, применяемом к BorderBrush, без использования прикрепленного свойства. Но если вы хорошо делаю это без стиля:

<Border x:Name="myBorder"> <!-- Style applied here --> 
    <StackPanel Background="{Binding Background, ElementName=myBorder}" ... 

это также можно сделать с помощью безымянной границы с {Binding Background, RelativeSource={RelativeSource FindAncestor,Border,1}.

Если вы хотите сделать это целиком в стиле, вам нужно будет добавить код. В принципе, создайте класс с прикрепленным свойством с именем «MyBindingTools.BindChildBackgroundToMyBackground». Добавить PropertyChangedCallback так, что, когда это свойство имеет значение «истина», привязка создается на ребенка, в основном:

BindingOperations.SetBinding(border, BackgroundProperty, new Binding("Background") { Source = this }); 

Кроме того, вы должны будете следить за имуществом ребенка на границе, так что, когда он изменяет связывание могут быть добавлены к новому Ребенку и удалены из старого Ребенка (если есть).

Я бы не рекомендовал вам делать это, если вам действительно не нужно. В вашей конкретной ситуации вы, вероятно, можете либо привязать ребенка вручную, либо создать шаблон, содержащий как пограничный, так и дочерний элемент управления. Любой из них будет лучшим решением, создающим прикрепленное свойство, как я описал.

+0

Первые два метода, которые вы предоставили, не сработали, я получил ту же ошибку. Мне нужно установить Background & BorderBrush of the Border и Background of child внутри границы для того же цвета (этот цвет отличается для всех моих элементов управления). Возможно ли это с помощью стилей? – codymanix

+0

Я тебя не понимаю. Если вы хотите, чтобы каждый элемент управления был другого цвета, где вы получите этот цвет? Связывание данных? Если это так, вы можете поместить выражение привязки в стиль. В любом случае, для вашего простого случая вы можете установить Border.BorderBrush и child.Background для Brushes.Transparent, что приведет к тому, что будет открыт только фон Border. Это будет очень похоже на установку всех трех одинаковых цветов (граница будет немного меньше, так как не будет никакого хода). –

+0

Вы считаете, что удаление класса ElementBorder целиком и использование вызывает ошибку области имени (т. Е. Влияет на имя StackPanel), но она отлично работает, если вы делаете то же самое, но оставьте атрибут Style =? Или я тоже вас не понимаю? –

0

Название области видимости путем поиска логического дерева.

Если вы прокатка собственной границы (в отличие от подклассов класса Border), проблемы названия сферы применения может быть вызваны следующими причинами:

  • В противном случае вызвать AddLogicalChild
  • Не правильно перекрывая LogicalChildren перечисления

С другой стороны, если вы подклассифицируете существующую границу (или любой декоратор), она будет обрабатывать логическое дерево.

Это также может быть вызвано, если на вашей границе установлен явный указатель NameScope. В этом случае имя будет назначено, но FindName не найдет его на уровне Window/UserContol/template.

Проводка соответствующих разделов класса ElementBorder может помочь нам дать вам лучший ответ.

+0

Спасибо за ответ. Я редактировал свой вопрос, чтобы дать вам больше информации. – codymanix

0

Это известно как NameScope проблемы Проверьте здесь для получения более подробной информации: http://dotnet.dzone.com/news/c-and-wpf-namescope-my-name-is

+0

Спасибо за ссылку, но я все еще не знаю, как решить мою проблему. В статье предлагается вызвать container.RegisterName («myname», кнопка), но как это можно сделать в xaml, чтобы он генерировал переменную «myname»? – codymanix

+0

Сначала вам нужно определить применяемый шаблон, получив значение свойства Шаблон элемента управления, в котором применяется шаблон. Затем вы вызываете версию шаблона FindName, передавая элемент управления, где шаблон был применен в качестве второго параметра. – viky

 Смежные вопросы

  • Нет связанных вопросов^_^