Błąd podczas wiązania właściwości zależności na niestandardowym zachowaniu

Badam mechanizm dołączonych zachowań Silverlight w celu użycia wzorca Model-View-ViewModel w moich aplikacjach Silverlight. Na początek staram się uzyskać prostą funkcjonalność Hello World, ale całkowicie utknąłem w błędzie, którego nie jestem w stanie znaleźć.

Mam teraz stronę, która zawiera przycisk, który po kliknięciu powinien wyświetlać komunikat. Zdarzenie click jest obsługiwane za pomocą klasy pochodzącej z Behavior, a komunikat jest określony jako właściwość zależności samego zachowania. Problem pojawia się, gdy próbujesz powiązać właściwość message z właściwością klasy viewmodel używanej jako kontekst danych: otrzymuję wyjątek w wywołaniuInitializeComponent w widoku.

Oto cały kod, którego używam, jak widać, jest raczej prosty. Najpierw znacznik strony głównej i widok, który zawiera:


Moja strona

<UserControl x:Class="MyExample.MyPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyExample"
    >
    <Grid x:Name="LayoutRoot">
        <local:MyView/>
    </Grid>
</UserControl>


Mój widok (TextBlock jest tylko po to, aby sprawdzić, czy składnia powiązania jest poprawna)

<UserControl x:Class="MyExample.MyView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:local="clr-namespace:MyExample"
    Width="400" Height="300">
    <StackPanel Orientation="Vertical" x:Name="LayoutRoot" Background="White">
        <StackPanel.Resources>
            <local:MyViewmodel x:Key="MyResource"/>
        </StackPanel.Resources>
        <TextBlock Text="This button will display the following message:"/>
        <TextBlock Text="{Binding MyMessage, Source={StaticResource MyResource}}" FontStyle="Italic"/>
        <Button x:Name="MyButton" Content="Click me!">
            <i:Interaction.Behaviors>
                <local:MyBehavior Message="{Binding MyMessage, Source={StaticResource MyResource}}"/>
            </i:Interaction.Behaviors>
        </Button>
    </StackPanel>
</UserControl>


Teraz kod, są dwie klasy: jedna dla zachowania i druga dla modelu widoku:

MyViewmodel

public class MyViewmodel
{
    public string MyMessage
    {
        get { return "Hello, world!"; }
    }
}


Moje zachowanie

public class MyBehavior : Behavior<Button>
{
    public static readonly DependencyProperty MessageProperty =
        DependencyProperty.Register("Message",
        typeof(string), typeof(MyBehavior),
        new PropertyMetadata("(no message)"));

    public string Message
    {
        get { return (string)GetValue(MessageProperty); }
        set { SetValue(MessageProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Click += new RoutedEventHandler(AssociatedObject_Click);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.Click -= new RoutedEventHandler(AssociatedObject_Click);
    }

    void AssociatedObject_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(Message);
    }
}


Prosty, ale ten kod rzucaAG_E_PARSER_BAD_PROPERTY_VALUE [Line: 15 Position: 43] (po prawej na początku wartości ustawionej dla właściwości Message) wyjątek podczas uruchamiania. Jestem pewien, że coś mi brakuje, ale co?

Dodatkowe informacje: jeśli usuwam powiązanie z właściwości Message na MyBehavior (to znaczy, jeśli ustawię jego wartość na dowolny ciąg statyczny), działa dobrze. Poza tym mam na celu silverlight 3 RTW.

Wielkie dzięki!


AKTUALIZACJA

Wydaje się, że w przeciwieństwie do WPF, Silverlight nie obsługuje powiązania danych na żadnym obiekcie pochodzącym z DependencyObject, ale tylko na obiektach pochodzących z FrameworkElement. Nie dotyczy to zachowania, dlatego wiązanie nie działa.

Znalazłem obejścietutaj, w formie czegoś o nazwie spoiwa zastępcze. Zasadniczo określasz element i właściwość, która ma być powiązana, a także wartość, jako atrybuty obiektu FrameworkElement zawierającego obiekt inny niż FrameworkElement.


AKTUALIZACJA 2

Zastępcze spoiwo nie działa, gdy FrameworkElement zawiera podelement Interaction.Behaviors.

Znalazłem inne rozwiązanietutaji ten wydaje się działać. Tym razem używaną sztuczką jestDeepSetter. Definiujesz jeden z takich ustawników jako statyczny zasób na zawierającym StackPanel, a następnie odwołujesz się do zasobu z zachowania. W moim przykładzie powinniśmy rozwinąć sekcję zasobów StackPanel w następujący sposób:

<StackPanel.Resources>
    <local:MyViewmodel x:Key="MyResource"/>
    <local:DeepSetter 
        x:Key="MyBehaviorSetter"
        TargetProperty="Message"
        BindingExport="{Binding MyMessage, Source={StaticResource MyResource}}"/>
</StackPanel.Resources>

... i zmodyfikuj deklarację zachowania przycisku w następujący sposób:

<local:MyBehavior local:DeepSetter.BindingImport="{StaticResource MyBehaviorSetter}"/>

AKTUALIZACJA 3

Dobra wiadomość: powiązanie danych dla dowolnego DependecyObject będzie dostępne w Silverlight 4:http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx#dobind

questionAnswers(1)

yourAnswerToTheQuestion