Reputation: 29468
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); }
}
Upvotes: 1
Views: 1970
Reputation: 101565
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>
Upvotes: 2
Reputation: 2273
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.
Upvotes: 0
Reputation: 204129
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" />
..
Upvotes: 1