3

У меня есть следующий сценарий:Наследование пользовательского контроля Silverlight. Повторное использование шаблона?

[TemplatePart(Name = GoToEditModeButtonPart, Type = typeof(DoubleClickButton))] 
public class ValueBoxWithLabel : ContentControl 
{ 
    public const string GoToEditModeButtonPart = "GoToEditModeButtonPart"; 

    #region LabelText Dependency Property ... 

    #region IsInEditMode Dependency Property ... 

    public event EventHandler<ModeChangedEventArgs> ModeChanged; 

    public ValueBoxWithLabel() 
    { 
     DefaultStyleKey = typeof (ValueBoxWithLabel); 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     //IsInEditMode invokes ModeChanged in the dependency property 
     ((DoubleClickButton) GetTemplateChild(GoToEditModeButtonPart)).DoubleClick += (sender, args) => IsInEditMode = true; 
    } 

    private void InvokeModeChanged(ModeChangedEventArgs e) 
    { 
     EventHandler<ModeChangedEventArgs> mode = ModeChanged; 
     if (mode != null) 
      mode(this, e); 
    } 
} 

ValueBox необходима панель для любого InputBox. Это просто сейчас, но будет использоваться повторно во всем приложении и будет содержать более сложное поведение и макет.

TextBox в качестве входных данных является обязательным используется, поэтому я сделать этот контроль:

public class TextBoxWithLabel : ValueBoxWithLabel 
{ 
    #region Text Dependency Property ... 

    public TextBoxWithLabel() 
    { 
     DefaultStyleKey = typeof (TextBoxWithLabel); 
    } 
} 

Я тогда текущий Generic.xaml, который не работает, но это дает в идее о том, что я хочу:

<ResourceDictionary> 

<ControlTemplate x:Key="ValueBoxWithLabelTemplate"> 
    <StackPanel Style="{StaticResource ValueBoxWithLabelPanelStyle}"> 
     <TextBlock Style="{StaticResource LabelStyle}" Text="{TemplateBinding LabelText}" /> 
     <Grid> 
      <ContentPresenter Content="{TemplateBinding Content}" /> 
      <local:DoubleClickButton Background="Black" x:Name="GoToEditModeButtonPart"></local:DoubleClickButton> 
     </Grid> 
    </StackPanel> 
</ControlTemplate> 

<Style TargetType="local:ValueBoxWithLabel"> 
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" /> 
</Style> 

<Style TargetType="local:TextBoxWithLabel"> 
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" /> 
    <Setter Property="Content"> 
     <Setter.Value> 
      <TextBox Style="{StaticResource ValueBoxStyle}" Text="{TemplateBinding Text}" /> 
     </Setter.Value> 
    </Setter> 
</Style> 

Поскольку ValueBoxWithLabel наиболее используется с TextBox я хочу, чтобы сделать контроль за этим, который повторно использует один и тот же шаблон, так что я не нужно копировать/вставить шаблон, и у них есть голова, поддерживающая оба последних с теми же изменениями.

Как можно повторно использовать ValueBoxWithLabelTemplate и переопределить свойство содержимого, сохраняя остальную часть шаблона?

ответ

1

Его интригующий подход. Я сам не пробовал, но похоже, что подход может работать.

Проблема, которую вы сейчас имеете, заключается в том, что вы пытаетесь использовать свойство Content объекта ContentPresenter. Однако для этого требуется конкретный экземпляр элемента управления, который в этом случае вы делаете с TextBox. Вы не можете использовать TemplateBinding в TextBox, потому что он не является частью ControlTemplate.

Даже без вопроса TemplateBinding вы могли бы создать один элемент управления с ним в любом случае, так как вы не можете «повторно использовать» один и тот же экземпляр TextBox в нескольких местах. Вот почему у нас есть шаблоны на первом месте.

Шаблоны весь путь

Решение проблемы шаблонный не должно быть трудно. На самом деле обманом было бы найти способ привязать внутренний контроль содержимого специализированных элементов управления к свойствам специализированного класса. Это трудно сделать, если вы не можете использовать TemplateBinding.

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

<ControlTemplate x:Key="ValueBoxWithLabelTemplate"> 
    <StackPanel Style="{StaticResource ValueBoxWithLabelPanelStyle}"> 
     <TextBlock Style="{StaticResource LabelStyle}" Text="{TemplateBinding LabelText}" /> 
     <Grid> 
      <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" /> 
      <local:DoubleClickButton Background="Black" x:Name="GoToEditModeButtonPart"></local:DoubleClickButton> 
     </Grid> 
    </StackPanel> 
</ControlTemplate> 

TextBoxWithLabel становится: -

<Style TargetType="local:TextBoxWithLabel"> 
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" /> 
    <Setter Property="ContentTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <TextBox Style="{StaticResource ValueBoxStyle}" /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Это я думаю (без тестирования).

связующая Выпуск

Однако, как вы можете видеть связывание на Text имущество отсутствует.Теперь есть несколько вещей, которые я могу придумать, которые могут помочь вам решить эту проблему привязки, но они включают либо злоупотребление DataContext, либо создание подкласса ContentPresenter, чтобы помочь передать сквозные свойства из внешнего управления во внутреннее. Оба являются настоящими уродливыми.

Заключение

Для такого простого базового шаблона вы, вероятно, лучше дублировать шаблон, чем прыгать через все обручи, необходимые для того чтобы достигнуть своего рода повторного использования.

+0

Спасибо за отзыв. Пропаганда не получит время в этот уик-энд, но я попробую это в первую очередь в понедельник и отчитаю :-) –

+0

Привет, снова Энтони. Я обошел попытку твоего решения, но не повезло. Проблема заключается в том, что им не удалось получить доступ к «Детали» в шаблоне управления, поэтому следующая строка сверху не будет работать: ((DoubleClickButton) GetTemplateChild (GoToEditStateButtonPart)). DoubleClick + = (sender, args) = > IsInEditMode = true; Любые мысли? –

+0

У вас много хороших указателей на эту проблему. Из-за временного давления на наш текущий проект. У меня не было времени копать глубже. Я могу опубликовать более позднее. Спасибо за ваш вклад. –

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