【问题标题】:WPF Databinding in ControlTemplate not working C#ControlTemplate 中的 WPF 数据绑定不起作用 C#
【发布时间】:2016-11-15 10:06:31
【问题描述】:

我尝试将一个简单的布尔值绑定到控件模板中的复选框和数据触发器,但没有任何效果。该复选框仅用于测试目的。我已经浏览了这里的帖子,但是大多数问题是直接设置属性而不是样式引起的,从而覆盖了它。使用 mouseover 属性的数据触发器工作得很好。它只是绑定到不起作用的布尔值。

到目前为止我的代码: 码:

public partial class HostFrame : UserControl
{
    public bool test { get; set; }

    public HostFrame()
    {
        test = true;
        InitializeComponent();          
    }
}

Xaml:

<UserControl x:Class="OwnDrawingv2.Elements.HostFrame"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:OwnDrawingv2.Elements"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <Style TargetType="{x:Type local:HostFrame}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:HostFrame}">
                        <Grid Background="LightBlue" Name="host_grid">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="20"></RowDefinition>
                                    <RowDefinition Height="Auto"></RowDefinition>
                                </Grid.RowDefinitions>
                            <ContentPresenter Name="content" Grid.Row="1" Grid.Column="1" />
                            <CheckBox Grid.Column="0" Grid.Row="0" IsChecked="{Binding Path=test}"> <!--Test prupose-->
                            </CheckBox>
                            <Image Grid.Column="1" Grid.Row="0" Name="attention" Width="30" Height="30"  Source="/attention_icon.png">
                                <Image.Style>
                                    <Style TargetType="Image">
                                        <Setter Property="Visibility" Value="Visible"></Setter>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=test}" Value="true">

                                                <Setter Property="Visibility" Value="Hidden"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Image.Style>
                            </Image>
                            <Ellipse Grid.Column="0" Grid.Row="1" Width="10" Height="10"  Fill="Black">
                                <Ellipse.Style>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Visibility" Value="Hidden"></Setter>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding ElementName=content, Path=IsMouseOver}" Value="true">
                                                <Setter Property="Visibility" Value="Visible"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Ellipse.Style>
                            </Ellipse>
                            <Ellipse Grid.Column="2" Grid.Row="1" Width="10" Height="10"  Fill="Black">
                                <Ellipse.Style>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Visibility" Value="Hidden"></Setter>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding ElementName=content, Path=IsMouseOver}" Value="true">
                                                <Setter Property="Visibility" Value="Visible"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Ellipse.Style>
                            </Ellipse>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
</UserControl>

更新:我得到了原始问题的答案,我理解这一点。但是为什么网络上有教程,似乎没有相关资源就可以工作? UPDATE2:我错过了一个关于 Datacontext 的答案信息,谢谢。问题已经解决了。

【问题讨论】:

  • 首先,您的test 属性缺少属性更改通知机制。由于该属性是在 UserControl 中声明的,因此它当然应该是一个依赖属性(通知值更改)。其次,DataTrigger 绑定缺少源对象。试试{Binding Path=test, RelativeSource={RelativeSource AncestorType=UserControl}}
  • 您好,非常感谢。对于第一部分:此实现将在稍后进行;)您可以发布此内容,我会将其标记为答案。

标签: c# wpf visual-studio-2015


【解决方案1】:

您还没有为您的UserControl 设置Datacontext,因此我认为它将为空。您应该会在输出中看到绑定错误。

另一方面,您的属性test 不会通知更改。如果它属于 UserControl(而不是 ViewModel 的一部分),则应将其声明为依赖属性

【讨论】:

  • 您永远不应该显式设置 UserControl 的 DataContext,因为这会阻止从 UserControl 的父级继承 DataContext。相反,请始终在 UserControl 的 XAML 中使用 RelativeSourceElementName 绑定。
  • @Clemens,你是对的,但我们缺乏关于如何使用 UserControl 的信息,如果它有父级或没有父级。我的意思不是“为它显式设置 DataContext”,而是“确保它具有某种 DataContext”。我不够清楚。
【解决方案2】:

如果您执行以下IsChecked="{Binding Path=test}",则意味着您的 UserControl 类是它自身的 DataContext(或者您没有这么说)。 所以你有 2 个解决方案(我猜)

1- 将您的 Test 属性移动到您的 ViewModel 并进行绑定。 2- 使用 RelativeResource 和 FindAncestor 方法 ({Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}})

PS:如果你的 HostFrame 继承自 Control,UIELement...,最好定义一个 DependencyProperty 并做一个 TemplateBinding

【讨论】:

  • 感谢您的提示,现在我正在寻找一些文档/教程以获取有关该主题的更多信息。有链接吗?
  • this link是一个简单的TemplateBinding教程
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2012-04-02
  • 1970-01-01
  • 2011-08-19
相关资源
最近更新 更多