列表视图中的 WPF 样式 ContentControl

问题描述

我为 ContentControl 设计了这种样式:

<UserControl.Resources>

    <DataTemplate x:Key="textBox">
        <TextBox Text="edit me"/>
    </DataTemplate>
    <DataTemplate x:Key="textblock">
        <TextBlock Text="can't edit"/>
    </DataTemplate>

 <Style x:Key="ContentControlStyle" targettype="{x:Type ContentControl}">
            <Setter Property="Content" Value="{Binding}"/>
            <Setter Property="ContentTemplate" Value="{StaticResource textblock}" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListViewItem},AncestorLevel=1}}" 
                                             Value="True">
                    <Setter Property="ContentTemplate" Value="{StaticResource textBox}" />
                </DataTrigger>
            </Style.Triggers>
  </Style>
</UserControl.Resources>

还有那个代码

<ListView.View>
            <GridView  x:Name="UGridview1">
                <GridViewColumn Width=" 90">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ContentControl >
                                
                            </ContentControl>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>

但是我想动态创建列,所以我写了以下代码

for (x = 0; x <= Lvobj.obj.Length - 1; x++) // ClmnCount - 1
    {
       
        GridViewColumn_ = new GridViewColumn();
        GridViewColumn_.SetValue(NameProperty,"Column" + x);
        GridViewColumn_.Header = Lvobj.obj(x)(clmntxt);
        GridViewColumn_.Width = 99;


        /// This part doesnt work
        ContentControl cntr = new ContentControl();
        cntr.Style = this.Resources("ContentControlStyle");
        ///
       
        GridViewColumn_.CellTemplate = cntr.ContentTemplate;
        UGridview1.Columns.Add(GridViewColumn_);
    }

它永远不会奏效。我必须做什么才能使用 ContentControl 样式创建列?

解决方法

使用带有 XamlReader.ParseDynamicResource API:

const string Xaml = @"<DataTemplate " +
    @"xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> " +
    @"<ContentControl Style=""{DynamicResource ContentControlStyle}"" />" +
    "</DataTemplate>";
DataTemplate DataTemplate_ = System.Windows.Markup.XamlReader.Parse(Xaml) as DataTemplate;
GridViewColumn_.CellTemplate = DataTemplate_;

或者创建一个FrameworkElementFactory

FrameworkElementFactory cc = new FrameworkElementFactory(typeof(ContentControl));
cc.SetValue(ContentControl.StyleProperty,this.Resources["ContentControlStyle"]);
GridViewColumn_.CellTemplate = new DataTemplate() { VisualTree = cc };
,

使用方括号访问 ResourceDictionary(它是一个 Dictionary):

this.Resources["ContentControlStyle"]

确保在调用 UserControl.OnInitialized 之前不要查找样式。您可以在 OnInitialized 中覆盖 UserControl,然后初始化 ListView。或者处理 Loaded 事件。

或者(推荐),考虑定义隐式样式(没有 x:key)。加载目标后,样式将自动应用。这样您就不必处理资源。
您可以通过在 ResourceDictionaryListView 中定义范围来限制范围:

<ListView>
  <ListView.Resources>
    <Style TargetType="{x:Type ContentControl}">
      <Setter Property="Content"
              Value="{Binding}" />
      <Setter Property="ContentTemplate"
              Value="{StaticResource textblock}" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsSelected,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListViewItem},AncestorLevel=1}}"
                     Value="True">
          <Setter Property="ContentTemplate"
                  Value="{StaticResource textbox}" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListView.Resources>

  <ListView.View>
    <GridView x:Name="UGridview1">
      <GridViewColumn Width=" 90">
        <GridViewColumn.CellTemplate>
          <DataTemplate>
            <ContentControl />
          </DataTemplate>
        </GridViewColumn.CellTemplate>
      </GridViewColumn>
    </GridView>
  </ListView.View>
</ListView>