【问题标题】:How to bind data to a user control using template selector如何使用模板选择器将数据绑定到用户控件
【发布时间】:2011-08-12 00:06:32
【问题描述】:

我在 WPF 中为数据网格使用模板选择器。

我有这个代码:

    <l:ProblemTemplateSelector x:Key="problemTemplateSelector">
        <l:ProblemTemplateSelector.ArithmeticTemplate>
            <DataTemplate>
                <Grid Background="LightBlue">
                    <l:ArithmeticUserControl Problem="{Binding ElementName=this}" />
                </Grid>
            </DataTemplate>
        </l:ProblemTemplateSelector.ArithmeticTemplate>
    </l:ProblemTemplateSelector>

在用户控件中,我需要在问题属性中设置所有元素,但我不知道我做错了什么。谢谢。

更新 1:

如果您需要详细信息,我会更具体,我有一个课程练习,用户控件在哪里:

public class Exercise : UserControl
{
    public static readonly DependencyProperty ProblemProperty = DependencyProperty.Register(
        "Problem", typeof(Problem), typeof(Exercise), new PropertyMetadata(null, ));

    public virtual Problem Problem
    {
        get
        {
            return (Problem)GetValue(ProblemProperty);
        }
        set
        {
            SetValue(ProblemProperty, value);
        }
    }
}

我还有另一个派生自练习的类。

public partial class ArithmeticUserControl : Exercise
{
    public ArithmeticUserControl()
    {
        InitializeComponent();
    }

    public override Problem Problem
    {
        get 
        { 
             return base.Problem;
        }
          set 
        { 
            base.Problem = value;

            Arithmetic p = (Arithmetic)value;
            Number1 = p.Number1;
            Number2 = p.Number2;
            Operator = p.Operation;
        }
     }
}

【问题讨论】:

  • 试试 ="{Binding TemplatedParent}",我说“所有元素”是模板化的元素对吗?
  • 可以,但是不行
  • 好的,您能否详细说明一下“所有元素”、控件本身或绑定到 ListBoxItem 的数据项时的意思?

标签: c# wpf xaml data-binding


【解决方案1】:

您应该能够将绑定声明为"{Binding}" 并将Problem 属性绑定到数据项。

编辑:看到您的示例后,您需要更改处理Problem 属性的方式。 WPF 绑定系统不使用 CLR 属性,因此 CLR 属性的存在是为了方便用户代码。因此,当通过绑定设置值时,您的属性中的代码永远不会被执行。

相反,您需要通过覆盖OnPropertyChanged 来处理属性值更改。例如,在您继承的类中:

protected override OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
    if(e.Property == ProblemProperty)
    {
        Arithmetic p = (Arithmetic)Problem;
        Number1 = p.Number1;
        Number2 = p.Number2;
        Operator = p.Operation;
    }
}

【讨论】:

  • @Oscar:您如何确定它不起作用?您是否在输出窗口中遇到绑定错误?您是否在监视 OnPropertyChanged 而它永远不会被调用 Problem
  • 我只是在属性中放置断点。那么,你认为我需要使用 OnPropertyChanged 吗?
  • @oscar.imbres:绑定系统不使用包装器,您需要在Register方法中注册属性更改回调(使用MetaData的重载并在MetaData中指定回调) 如果您想监控这些更改。
  • 怎么会超载?
  • @oscar:您将不得不覆盖OnPropertyChanged 或将处理程序附加到依赖属性本身(前者是更简单和更直接的选项,IMO)来检测更改。您的 C# 属性只是为了方便而存在,绑定系统不使用,这就是为什么您在其中使用 GetValueSetValue 很重要。
【解决方案2】:

只需使用{Binding} 在控件中传递数据项。 如果这没有帮助,请与您的控件一起添加一个 TextBlock 并查看通过直接绑定绑定的内容:

<Grid Background="LightBlue">                     
   <l:ArithmeticUserControl Problem="{Binding ElementName=this}" />                 
   <TextBlock Text="{Binding}" Background="Green" ></TextBlock>
</Grid> 

所以在绿色背景下,你应该看看 ListBoxItem 有什么

【讨论】:

  • 它表示类型名称。我不明白为什么没有分配问题属性
  • 你认为我需要对 MetaData 做一些事情吗?
猜你喜欢
  • 2011-12-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多