views:

368

answers:

3

Hi I want to do the following in xaml:

I have a property FocusTarget in my control class which I want to assign an UIElement from the current class. Is this possible in 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>

UPDATE: I now implemented the property as dependency property but it seems that no assignment occures, although I assign it in XAML. But there is not compile nor runtime error:

in xaml:

    FocusTarget="{Binding ElementName=myCtrl}"

in 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); }
    }
+1  A: 

Make sure FocusTarget is a dependency property, and bind your target control using an element binding:

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

Matt Hamilton
I tried it but my property values are null, although assigned in the xaml code, even the PropertyChangedCallback doesn't fire. What could gone wrong?
codymanix
I edited my question to show what I've done
codymanix
A: 

Binding syntax is of the form : Target = "{Binding Source}"

It is required by the framework that Target is always a dependency property, while source can just be a plain old CLR property.

Matt Hamilton's answer should work.

Trainee4Life
But it doesn't, at least for me :( See I edited my question.
codymanix
When dealing with binding issues, I generally search through the Output window to find any binding errors. They all start with System.Windows.DataError. So, are there any errors in the Output window?
Trainee4Life
No I don't see any errors.
codymanix
+1  A: 

There can be a bunch of reasons why {Binding ElementName=...} doesn't work for you. It does lookup via inherited context, which propagates through visual element tree. If there's no way to walk through visual tree from binding to element it is referencing, the binding will fail. For example, if my:CodeBlockControl is declared inside Resources, or in a ControlTemplate of some control, or if there is a Popup between it and root (including implicit one, such as e.g. introduced by ContextMenu), this is what will happen.

Unfortunately, there's no general-purpose way to reference any other element from the same XAML directly. There will be in .NET 4.0 XamlReader, though it will still be disabled for BAML (and, consequently, for WPF). One alternative is to use resources and {StaticResource} instead:

<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>
Pavel Minaev