【问题标题】:Specify static text value in a ContentControl with a DataTemplate使用 DataTemplate 在 ContentControl 中指定静态文本值
【发布时间】:2013-06-21 14:13:45
【问题描述】:

我正在创建一个应用程序,用于在单个窗口中编辑大量产品规格。

我有一堆尺寸(以英寸为单位),我想创建一个简单的模板,该模板将针对每个尺寸显示分数和十进制值的值。 它基本上是一个TextBlock,和两个TextBox。

但我不知道如何指定 TextBlock 的文本(在本例中为宽度)。
我希望能够在 ContentControl 声明(或类似声明)中指定它。

这是我的数据模板:

<Window.Resources>
    <DataTemplate x:Key="InchesInputTemplate">
        <StackPanel>
            <TextBlock Text="{Binding}" /> <!-- How should I define the binding ? -->
            <TextBox Text="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Content, Converter=InchesToFractionConverter}" />
            <TextBox Text="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Content}" />
        </StackPanel>
    </DataTemplate>
</Window.Resources>

然后我在 ContentControl 中使用它:

<ContentControl Content="{Binding Width}" 
                ContentTemplate="{StaticResource InchesInputTemplate}"
                LabelText="Width :" />

还有我的简化产品类(它将包含更多维度):

public class Product
{
    private string _productCode;

    public string ProductCode
    {
        get { return _productCode; }
        set { _productCode = value; }
    }

    private float _width;

    public float Width
    {
        get { return _width; }
        set { _width = value; }
    }
}

为我的每个维度指定标签文本的最佳方法是什么(在我的示例中为 LabelText 属性)?

【问题讨论】:

  • 您要绑定的 Inches 属性在哪里?浮动宽度属性与您绑定到内容的属性不同吗?如果您将复杂对象(具有 Inches 属性)作为 Content 传递,您可以在其上添加更多属性并在模板内绑定到它们。
  • @John Bowen 你是对的,我在这里犯了一个错误。起初我想为我的尺寸制作一个复杂的对象,但我意识到这不是必需的。我更正了绑定表达式。
  • 这更有意义,但新的绑定是不必要的复杂。父控件的 Content 已经是模板中的 DataContext 所以你可以使用 {Binding Converter=InchesToFractionConverter}

标签: c# wpf xaml


【解决方案1】:

您可以使用Tag 属性

<DataTemplate x:Key="InchesInputTemplate">
  <StackPanel>
    <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}, Path=Tag}" />
    <!--  How should I define the binding ?  -->
    <TextBox Text="{Binding Inches, Converter=InchesToFractionConverter}" />
    <TextBox Text="{Binding Inches}" />
  </StackPanel>
</DataTemplate>

<ContentControl Content="{Binding Width}" 
                ContentTemplate="{StaticResource InchesInputTemplate}"
                Tag="Width :" />

更新:

如果您不想使用Tag 属性,可以使用Attached Property

public class MyLabelPropertyClass {
  public static readonly DependencyProperty MyLabelTextProperty =
    DependencyProperty.RegisterAttached(
      "MyLabelText",
      typeof(string),
      typeof(MyLabelPropertyClass),
      new FrameworkPropertyMetadata(
        string.Empty, FrameworkPropertyMetadataOptions.Inherits));

  public static void SetMyLabelText(UIElement element, string value) {
    element.SetValue(MyLabelTextProperty, value);
  }

  public static string GetMyLabelText(UIElement element) {
    return (string)element.GetValue(MyLabelTextProperty);
  }
}

<DataTemplate x:Key="InchesInputTemplate">
  <StackPanel>
    <TextBlock Text="{Binding Path=(local:MyLabelPropertyClass.MyLabelText), RelativeSource={RelativeSource Self}}" />
...
</DataTemplate>
...
<ContentControl Content="{Binding Width}"
                ContentTemplate="{StaticResource InchesInputTemplate}"
                local:MyLabelPropertyClass.MyLabelText="Width :" />

备用

如果你想用普通的Dependency property 子类化ContentControl

public class MyCustomContentControl : ContentControl {
  public static readonly DependencyProperty MyLabelTextProperty =
    DependencyProperty.Register(
      "MyLabelText",
      typeof(string),
      typeof(MyCustomContentControl),
      new FrameworkPropertyMetadata(string.Empty));

  public string MyLabelText {
    get {
      return (string)GetValue(MyLabelTextProperty);
    }
    set {
      SetValue(MyLabelTextProperty, value);
    }
  }
}

<DataTemplate x:Key="InchesInputTemplate">
  <StackPanel>
    <TextBlock Text="{Binding Path=MyLabelText, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyCustomContentControl}}}" />
...
</DataTemplate>
...
<local:MyCustomContentControl ContentTemplate="{StaticResource InchesInputTemplate}"
                              MyLabelText="Width :" />

【讨论】:

  • 谢谢!好主意,它会起作用,但我更愿意避免使用标签。如果它真的是解决这个问题的最佳方法,我可能仍然会使用它(但我希望有一种更自然和 WPF 的方法来做到这一点)。
  • @igelineau 嗯,这是最快的,但是如果您不想使用 Tag 属性,那么您可以使用 Attached 属性(我已经用一个示例更新了我的答案)。如果您想进一步区分,请将ContentControl 子类化并为其添加一个依赖属性。
  • 使用依赖属性对 ContentControl 进行子类化很有趣,到目前为止,这似乎是一种更简洁的方法。我可能会在周末之后试试这个。谢谢!
  • @igelineau 我也用子类方法更新了我的答案。
猜你喜欢
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多