WPF中的DataTemplate资源和绑定

3

我有一个简化版的DataGrid如下:

<DataGrid ItemsSource="{Binding Something}">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Test">
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBox Text="{Binding A}"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding A}"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Test">
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBox Text="{Binding B}"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding B}"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</Datagrid>

有没有一种方法将DataTemplate移动到资源中,以便为不同的属性重用它,这样我就不必为每个属性复制和粘贴DataTemplate了?
2个回答

6

一个实用的解决方案是在资源级别上定义模板,并在每个列中使用“ContentPresenter”包装它们。您仍然需要明确为每个列定义模板。但是,您可以在一个地方管理模板,并快速查看哪些属性绑定到您的列。

<DataGrid>
     <!-- Templates in a single place in resources -->
     <DataGrid.Resources>
        <DataTemplate x:Key="CellTemplate">
           <TextBlock Text="{Binding}" />
        </DataTemplate>
        <DataTemplate x:Key="EditCellTemplate">
           <TextBlock Text="{Binding}" />
        </DataTemplate>
     </DataGrid.Resources>
     <DataGrid.Columns>
        <DataGridTemplateColumn>
           <DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                 <ContentPresenter Content="{Binding A}" ContentTemplate="{StaticResource CellTemplate}" />
                 </DataTemplate>
              </DataGridTemplateColumn.CellTemplate>
              <DataGridTemplateColumn.CellEditingTemplate>
                 <DataTemplate>
                    <ContentPresenter Content="{Binding A}" ContentTemplate="{StaticResource EditCellTemplate}" />
                 </DataTemplate>
              </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn>
               <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                     <ContentPresenter Content="{Binding B}" ContentTemplate="{StaticResource CellTemplate}" />
                  </DataTemplate>
               </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
               <DataTemplate>
                  <ContentPresenter Content="{Binding B}" ContentTemplate="{StaticResource EditCellTemplate}" />
               </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
         </DataGridTemplateColumn>
      </DataGrid.Columns>
</DataGrid>

对我来说,你回答中让我正常工作的关键是在ContentPresenter上设置了Content="{Binding}"。我之前使用的是DataContext="{Binding}",但它不起作用,但是将其更改为Content后,我终于使绑定工作了。 - Tam Bui

3
你可以这样做:
<DataGrid ItemsSource="{Binding Something}">
      <DataGrid.Resources>
         <DataTemplate x:key="MyTemplate">
             <Grid>
               <TextBox Text="{Binding}"/>
             </Grid>
         </DataTemplate>
      </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Test" 
                                    CellTemplate="{StaticResource MyTemplate}" 
                                    >
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </Datagrid>

但是你需要重新思考绑定逻辑,因为你需要在同一模板中为所有列使用单元格数据上下文。


据我所知,{Binding}将整个对象绑定到模板,那么我如何将特定属性绑定到模板列? - blackcat
@blackcat,没有什么可以阻止你在资源中拥有两个DataTemplates(一个用于绑定到A,另一个用于B),这仍然比四个更好。 - adminSoftDK
@adminSoftDK,我仍然需要四个数据模板(编辑和显示,其中我将拥有{Binding A}和{Binding B}),我正在寻找通用解决方案。 - blackcat
@adminSoftDK 让所有绑定类都遵循一个接口,模板只绑定到该接口,这样一个模板就可以适用于许多不同的对象类型。 - ΩmegaMan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接