【问题标题】:Use placeholders in controltemplate在 controltemplate 中使用占位符
【发布时间】:2013-10-16 18:40:08
【问题描述】:

我有许多布局几乎相同的网格。这是一个例子

 <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>

我想把它变成这样的控制模板:no template property on grid style in WPF?

但是当我使用控件模板时,如何更改 Textblock 文本和图像源?

【问题讨论】:

    标签: c# wpf controltemplate


    【解决方案1】:

    您可以通过创建一个具有 Text 和 Source 属性的模型来实现这一点。然后根据您要使用此 ControlTemplate 的不同实例数量,您可以在 Grid 的 Tag 中设置模型实例。

    <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>
    

    【讨论】:

      【解决方案2】:

      据我所知,您只能使用DataTemplate 执行此操作,并且如果您的每个数据绑定类都具有相同名称的属性,在本例中为TextValueImageSource。我不认为您可以直接从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}" />
      

      【讨论】:

        【解决方案3】:

        这可以通过数据绑定来完成,但最好使用属性接口,这样您就可以简单地键入如下内容:

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

        这样您就不需要将 UI 标签和图标放在单独的数据层中。

        这可以通过创建一个定义Dependency Properties的控件类,并在ControlTemplate中使用TemplateBindings绑定到它们来实现。

        现有控件可能具有您可以为其创建模板的适当属性。这个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不会自动转换。

        【讨论】:

          【解决方案4】:

          将 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>
          

          【讨论】:

            猜你喜欢
            • 2015-09-05
            • 2017-05-28
            • 2012-07-08
            • 2013-06-08
            • 1970-01-01
            • 2019-02-25
            • 1970-01-01
            • 2021-01-11
            • 1970-01-01
            相关资源
            最近更新 更多