Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行时在WPF DataTemplate中分配绑定路径_Wpf_Listview - Fatal编程技术网

在运行时在WPF DataTemplate中分配绑定路径

在运行时在WPF DataTemplate中分配绑定路径,wpf,listview,Wpf,Listview,我正在用C#编写一个WPF程序,其中有一个列表视图,运行时将为其填充列。我想为ListView中的GridViewColumn对象使用自定义数据模板 在我看到的示例中,列的数量是预先固定的,通常使用下面的XAML之类的东西创建自定义数据模板 <DataTemplate x:Key="someKey"> <TextBlock Text="{Binding Path=FirstName}" /> </DataTemplate> 稍后,还可以通过调用F

我正在用C#编写一个WPF程序,其中有一个列表视图,运行时将为其填充列。我想为ListView中的GridViewColumn对象使用自定义数据模板

在我看到的示例中,列的数量是预先固定的,通常使用下面的XAML之类的东西创建自定义数据模板

<DataTemplate x:Key="someKey">
    <TextBlock Text="{Binding Path=FirstName}" />
</DataTemplate>

稍后,还可以通过调用FindResource(“someKey”)将此DataTemplate分配给代码隐藏中的GridViewColumn.CellTemplate。但是,这一点对我来说没有任何用处,因为在本例中,Path元素被固定为FirstName。我真的需要一些我可以在代码中设置路径的东西


我的印象是,如果使用XamlReader,可能会有类似的事情发生,但我不确定在实践中我会如何做到这一点。非常感谢您提供的任何解决方案。

也许会对您有所帮助?或者您可以创建一个用户控件,将其绑定到足够大的对象上(每个列都是一样的)。然后让此控件根据它在
DataContext

中的内容计算出它应该显示的内容。使用两个协同工作的DataTemplate很容易构建您需要的内容:外部DataTemplate只需为内部DataTemplate设置DataContext,如下所示:

<DataTemplate x:Key="DisplayTemplate">
  <Border ...>
    <TextBlock Text="{Binding}" ... />
  </Border>
</DataTemplate>

<DataTemplate x:Key="CellTemplate">
  <ContentPresenter Content="{Binding FirstName}"
                    ContentTemplate="{StaticResource DisplayTemplate}" />
</DataTemplate>
这两种情况都会导致名为“DisplayTemplate”的DataTemplate用于在列中显示名字

助手类将实现为:

public class GVCHelper : DependencyObject
{
  public static string GetDisplayPath(DependencyObject obj) { return (string)obj.GetValue(DisplayPathProperty); }
  public static void SetDisplayPath(DependencyObject obj, string value) { obj.SetValue(DisplayPathProperty, value); }
  public static readonly DependencyProperty DisplayPathProperty = DependencyProperty.RegisterAttached("DisplayPath", typeof(string), typeof(GVCHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) => Update(obj)
  });

  public static DataTemplate GetTemplate(DependencyObject obj) { return (DataTemplate)obj.GetValue(TemplateProperty); }
  public static void SetTemplate(DependencyObject obj, DataTemplate value) { obj.SetValue(TemplateProperty, value); }
  public static readonly DependencyProperty TemplateProperty = DependencyProperty.RegisterAttached("Template", typeof(DataTemplate), typeof(GVCHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) => Update(obj)
  });

  private static void Update(DependencyObject obj)
  {
    var path = GetDisplayPath(obj);
    var template = GetTemplate(obj);
    if(path!=null && template!=null)
    {
      var factory = new FrameworkElementFactory(typeof(ContentPresenter));
      factory.SetBinding(ContentPresenter.ContentProperty, new Binding(path));
      factory.SetValue(ContentPresenter.ContentTemplateProperty, template);
      obj.SetValue(GridViewColumn.CellTemplateProperty,
        new DataTemplate { VisualTree = factory };
    }
  }
}
工作原理:只要设置了这两个属性,就会构造一个新的DataTemplate,并更新GridViewColumn.CellTemplate属性

var col = new GridViewColumn();
GVCHelper.SetDisplayPath(col, "FirstName");
GVCHelper.SetTemplate(col, (DataTemplate)FindResource("DisplayTemplate"));
public class GVCHelper : DependencyObject
{
  public static string GetDisplayPath(DependencyObject obj) { return (string)obj.GetValue(DisplayPathProperty); }
  public static void SetDisplayPath(DependencyObject obj, string value) { obj.SetValue(DisplayPathProperty, value); }
  public static readonly DependencyProperty DisplayPathProperty = DependencyProperty.RegisterAttached("DisplayPath", typeof(string), typeof(GVCHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) => Update(obj)
  });

  public static DataTemplate GetTemplate(DependencyObject obj) { return (DataTemplate)obj.GetValue(TemplateProperty); }
  public static void SetTemplate(DependencyObject obj, DataTemplate value) { obj.SetValue(TemplateProperty, value); }
  public static readonly DependencyProperty TemplateProperty = DependencyProperty.RegisterAttached("Template", typeof(DataTemplate), typeof(GVCHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) => Update(obj)
  });

  private static void Update(DependencyObject obj)
  {
    var path = GetDisplayPath(obj);
    var template = GetTemplate(obj);
    if(path!=null && template!=null)
    {
      var factory = new FrameworkElementFactory(typeof(ContentPresenter));
      factory.SetBinding(ContentPresenter.ContentProperty, new Binding(path));
      factory.SetValue(ContentPresenter.ContentTemplateProperty, template);
      obj.SetValue(GridViewColumn.CellTemplateProperty,
        new DataTemplate { VisualTree = factory };
    }
  }
}