c# - 如何在样式内的 WPF DataTemplate 中使用绑定(bind)

标签 c# .net wpf templates binding

我是 WPF 数据绑定(bind)/样式/模板的新手... 我正在尝试通过使用样式将一组属性值应用于按钮。样式绑定(bind)到类的字段。如您所见,这对 BackColor 属性很有效。但是当我尝试设置 TextBlock 的文本时,它不起作用(我也没有收到绑定(bind)错误)。我的最终目标是也能够将图像设置为内容。

当我不使用 DataTemplate 并使用 SetterProperty="Content"而不是 "ContentTemplate"时,它将适用于一个按钮,但是当添加第二个按钮时,它会给我一个运行时错误“指定的元素已经是逻辑的另一个元素的子元素。先断开它。”

我在这里错过了什么?我要在“TextBlock Text=”中输入什么????

顺便说一句。我想在它工作后将样式移动到全局范围,所以我不想使用任何明确引用 MyClass

<Window.Resources>
    <Style TargetType="Button" x:Key="MyStyle">
        <Setter Property="Background" Value="{Binding BackColor}"/>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="XYZ-"/>
                        <TextBlock Text="{Binding Text}"/>
                    </StackPanel>                        
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel Orientation="Horizontal" Height="30">
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action1}"/>
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action1}"/>
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action2}"/>
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action2}"/>
</StackPanel>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;

        Action1 = new MyClass() { Text = "ACTION1", BackColor = new SolidColorBrush(Colors.Red) };
        Action2 = new MyClass() { Text = "ACTION2", BackColor = new SolidColorBrush(Colors.Green) };
    }
    public MyClass Action1{get; private set;}
    public MyClass Action2{get; private set;}
}

public class MyClass
{
    public string Text { get; set; }
    public Brush BackColor { get; set; }
}

最佳答案

在你原来的问题中,你需要

<Setter Property="Background" Value="{Binding BackColor}"/>
<Setter Property="Content" Value="{Binding Text}"/>

现在你需要使用相对源绑定(bind)

<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
           AncestorType=Button}, Path=DataContext.Text}"/>

但是,您最好按如下方式使用 ItemsControl

XAML

<Page.Resources>
    <DataTemplate x:Key="ItemTemplate" DataType="{x:Type Samples:MyClass}">
        <Button Background="{Binding BackColor}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="XYZ-"/>
                <TextBlock Text="{Binding Text}"/>
            </StackPanel>
        </Button>
    </DataTemplate>
  <ItemsPanelTemplate x:Key="ItemsPanelTemplate">
        <StackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
</Page.Resources>
<Page.DataContext>
    <Samples:DataTemplateItemsControlViewModel/>
</Page.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ItemsControl 
        ItemsSource="{Binding Items}" 
        ItemsPanel="{StaticResource ItemsPanelTemplate}"
        ItemTemplate="{StaticResource ItemTemplate}"/>
</Grid>

C#

public class DataTemplateItemsControlViewModel
{
    public DataTemplateItemsControlViewModel()
    {
        Items =
            new Collection<MyClass>
                {
                    new MyClass
                        {
                            Text = "ACTION1", 
                            BackColor = new SolidColorBrush(Colors.Red)
                        },
                    new MyClass
                        {
                            Text = "ACTION2", 
                            BackColor = new SolidColorBrush(Colors.Blue)
                        },
                    new MyClass
                        {
                            Text = "ACTION3", 
                            BackColor = new SolidColorBrush(Colors.Green)
                        },
                    new MyClass
                        {
                            Text = "ACTION4", 
                            BackColor = new SolidColorBrush(Colors.Yellow)
                        },
                };
    }

    public IList<MyClass> Items { get; private set; }
}

关于c# - 如何在样式内的 WPF DataTemplate 中使用绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9896084/

相关文章:

c# - 创建 ThreadLocal EF 上下文

c# - 如何在 asp :gridview 中动态创建列

.net - 为什么 Visual Studio 2012 会引用错误版本的程序集?

wpf - 在 Model V/s ViewModel 中使用 IDataErrorInfo

c# - 嵌入式wpf文本框不接受输入

c# - WPF 中的选项卡式文档界面仅使用板载方式?

c# - 包装 NLog 时如何保留调用点信息

带有 XML 结构化数据的 C# HttpWebRequest

c# - 使用现有表的代码优先迁移

c# - 找不到对 System.Diagnostics.Stopwatch 的引用