WPF:将子元素分配给XAML中的属性

WPF:将子元素分配给XAML中的属性,wpf,xaml,controls,properties,Wpf,Xaml,Controls,Properties,嗨,我想在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"

嗨,我想在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>
在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); }
    }

确保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" />
    ..

..
..

绑定语法的形式为:Target=“{Binding Source}”

框架要求目标始终是一个依赖属性,而源只能是一个普通的旧CLR属性


马特·汉密尔顿的答案应该行得通。

有很多原因可以解释为什么
{Binding ElementName=…}
不适合你。它通过继承的上下文进行查找,该上下文通过可视元素树传播。如果无法遍历视觉树,从绑定到它所引用的元素,绑定将失败。例如,如果
my:CodeBlockControl
是在
Resources
中声明的,或者在某个控件的
ControlTemplate
中声明的,或者如果它和根目录之间有一个
弹出窗口(包括隐式弹出窗口,例如由
ContextMenu
引入),则会发生这种情况

不幸的是,没有通用的方法直接引用同一XAML中的任何其他元素。在.NET4.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>

...
...

我尝试了它,但我的属性值为null,尽管在xaml代码中赋值,但即使PropertyChangedCallback也不会启动。在处理绑定问题时,我通常会搜索输出窗口以查找任何绑定错误。它们都以System.Windows.DataError开头。那么,输出窗口中是否有错误?您的“验证”回调是否会以某种方式停止分配?可能值得暂时评论一下,看看它是否开始工作。不,这是一个什么也不做,但总是返回True的方法。当我尝试创建一个完整控件时,我遇到了属性未设置的问题;我的自定义控件是从UIElement派生的。教训:按照手册中的说明从控件中派生!
<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>