【问题标题】:WPF: assign child element to property in XAMLWPF:将子元素分配给 XAML 中的属性
【发布时间】:2010-11-29 08:09:24
【问题描述】:

您好,我想在 xaml 中执行以下操作:

我的控件类中有一个属性 FocusTarget,我想从当前类中分配一个 UIElement。这在 XAML 中可行吗?

<my:BaseControl x:Class="SectionControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    FocusTarget="myCtrl">   // this fails           
       ..       
       <my:CodeBlockControl x:Name="myCtrl" />           
       ..       
</my:BaseControl>

更新: 我现在将该属性实现为依赖属性,但似乎没有发生分配,尽管我在 XAML 中分配了它。但是没有编译也没有运行时错误:

在xml中:

    FocusTarget="{Binding ElementName=myCtrl}"

在cs中:

   public static readonly DependencyProperty FocusTargetProperty;      

    static BaseControl()
    {
        FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(null);
        FocusTargetProperty = DependencyProperty.Register("FocusTarget", typeof(FrameworkElement), typeof(BaseControl), metadata, Validate);
   }

    public FrameworkElement FocusTarget
    {
        get { return GetValue(FocusTargetProperty)as FrameworkElement; }
        set { SetValue(FocusTargetProperty, value); }
    }

【问题讨论】:

  • 您的“验证”回调会以某种方式停止分配吗?可能值得暂时评论一下,看看它是否开始工作。
  • 不,这是一个除了总是返回 true 什么都不做的方法
  • 当我尝试使用快捷方式制作一个完整的控件时,我遇到了属性未设置的问题;我的自定义控件是从 UIElement 派生的。教训:如手册所说,从 Control 派生!

标签: wpf xaml controls properties


【解决方案1】:

确保 FocusTarget 是一个依赖属性,并使用元素绑定来绑定目标控件:

<my:BaseControl x:Class="SectionControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    FocusTarget="{Binding ElementName=myCtrl}">
    ..
    <my:CodeBlockControl x:Name="myCtrl" />
    ..

【讨论】:

  • 我试过了,但我的属性值为 null,尽管在 xaml 代码中分配,即使 PropertyChangedCallback 也不会触发。出了什么问题?
【解决方案2】:

绑定语法格式为:Target = "{Binding Source}"

框架要求 Target 始终是依赖属性,而 source 只能是普通的旧 CLR 属性。

马特汉密尔顿的答案应该有效。

【讨论】:

  • 在处理绑定问题时,我通常会通过“输出”窗口查找任何绑定错误。它们都以 System.Windows.DataError 开头。那么,输出窗口中是否有任何错误?
【解决方案3】:

{Binding ElementName=...} 不适合您的原因可能有很多。它通过继承的上下文进行查找,该上下文通过可视元素树传播。如果无法从绑定到它所引用的元素遍历可视化树,则绑定将失败。例如,如果my:CodeBlockControl 声明在Resources 内部,或者在某个控件的ControlTemplate 中,或者如果它与根之间存在Popup(包括隐含的,例如ContextMenu 引入的) ,这就是将要发生的事情。

不幸的是,没有通用的方法可以直接从同一个 XAML 中引用任何其他元素。在 .NET 4.0 XamlReader 中将会有,尽管它仍将被 BAML 禁用(因此,对于 WPF)。一种替代方法是使用资源和{StaticResource}

<my:BaseControl x:Class="SectionControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    FocusTarget="{StaticResource myCtrl}">

  <my:BaseControl.Resources>
    <my:CodeBlockControl x:Key="myCtrl" />
  </my:BaseControl.Resources>

  ...
  <!-- where it originally was -->
  <StaticResource ResourceKey="myCtrl"/>
  ...

</my:BaseControl>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    相关资源
    最近更新 更多