2013-10-09 1 views
0

У меня есть ряд сеток, которые имеют почти одинаковый макет. Это примерИспользование заполнителей в контрольной таблице

<Grid x:Name="OptionChangeUserState" Grid.Row="0" Style="{StaticResource MenuItemGridStyle}"> 
     <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="30" /> 
     </Grid.ColumnDefinitions> 

     <TextBlock Grid.Column="0" Style="{StaticResource MenuItemTextblockStyle}" Text="Status wijzigen" Margin="0"/> 
     <Image Grid.Column="1" Source="/UserControlSolution;component/Image/user.png" Margin="5" /> 
</Grid> 

Я хочу, чтобы превратить это в ControlTemplate, как здесь: no template property on grid style in WPF?

Но как я могу изменить текст TextBlock и источник изображения, когда я использую ControlTemplate?

ответ

2

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

<local:MyModel x:Key="myModel1" Text="" Source=""/> 


<ContentControl Tag="{StaticResource myModel1}" Template={StaticResource myTemplate}> 
</ContentControl> 

и в шаблоне

<ControlTemplate x:Key="myTemplate" TargetType="ContentControl"> 
<Grid x:Name="OptionChangeUserState" Grid.Row="0" Style="{StaticResource MenuItemGridStyle}"> 
     <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="30" /> 
     </Grid.ColumnDefinitions> 

     <TextBlock Grid.Column="0" Style="{StaticResource MenuItemTextblockStyle}" Text="{Binding Tag.Text, RelativeSource={RelativeSource TemplatedParent}}" Margin="0"/> 
     <Image Grid.Column="1" Source="{Binding Tag.Source, RelativeSource={RelativeSource TemplatedParent}}" Margin="5" /> 
</Grid> 
</ControlTemplate> 
+0

+1 для вашего интересного использования свойства 'Tag'. – Sheridan

+0

спасибо @Sheridan :) – Nitin

1

Насколько я знаю, вы можете сделать это только с DataTemplate и только если каждый из ваших данных связаны классы имели свойства одного и того же имени, в этом случае TextValue и ImageSource. Я не думаю, что вы можете получить доступ к объекту данных непосредственно из ControlTemplate.

<DataTemplate> 
    <Grid x:Name="OptionChangeUserState" Grid.Row="0" Style="{StaticResource MenuItemGridStyle}"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="30" /> 
     </Grid.ColumnDefinitions> 
     <TextBlock Grid.Column="0" Style="{StaticResource MenuItemTextblockStyle}" Text="{Binding TextValue}" Margin="0"/> 
     <Image Grid.Column="1" Source="{Binding ImageSource}" Margin="5" /> 
    </Grid> 
</DataTemplate> 

Вы также должны были бы использовать ContentTemplate свойство вместо этого.

<ContentControl Content="{Binding DataObject}" 
    ContentTemplate="{StaticResource Template}" /> 
0

Использование DataTemplate с помощью своего рода DTO, DictionaryEntry будет работать для двух элементов.

<DataTemplate DataType="{x:Type Collections:DictionaryEntry}" x:Key="gridTemplate"> 
     <Grid Style="{StaticResource MenuItemGridStyle}"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition Width="30" /> 
      </Grid.ColumnDefinitions> 

      <TextBlock Grid.Column="0" Style="{StaticResource MenuItemTextblockStyle}" Text="{Binding Key}" Margin="0"/> 
      <Image Grid.Column="1" Source="{Binding Value}" Margin="5" /> 
     </Grid> 
    </DataTemplate> 

Использование:

<ContentControl ContentTemplate="{StaticResource gridTemplate}"> 
<ContentControl.Content> 
    <Collections:DictionaryEntry Key="Status wijzigen" Value="/UserControlSolution;component/Image/user.png" /> 
</ContentControl.Content> 

1

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

<local:OptionControl Text="Status wijzigen" ImageSource="/UserControlSolution;component/Image/user.png" /> 

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

Это может быть достигнуто путем создания класса управления, который определяет Dependency Properties, и используя TemplateBindings для привязки к ним в ControlTemplate.

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

<Style x:Key="HeaderedContentControlStyle" TargetType="HeaderedContentControl"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="HeaderedContentControl"> 
       <Grid Style="{StaticResource MenuItemGridStyle}"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*" /> 
         <ColumnDefinition Width="30" /> 
        </Grid.ColumnDefinitions> 

        <TextBlock Grid.Column="0" Style="{StaticResource MenuItemTextblockStyle}" Text="{TemplateBinding Header}" /> 
        <Image Grid.Column="1" Source="{TemplateBinding Content}" /> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Использование:

<HeaderedContentControl Name="OptionChangeUserState" Grid.Row="0" 
         Style="{StaticResource HeaderedContentControlStyle}" 
         Header="Status wijzigen"> 
    <BitmapImage>/UserControlSolution;component/Image/user.png</BitmapImage> 
</HeaderedContentControl> 

Обратите внимание, что нам нужно, чтобы обернуть путь изображения в BitmapImage явно. Это связано с тем, что свойство HeaderedContentControl.Content не объявлено как тип изображения, поэтому WPF не будет автоматически его преобразовывать.