Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: binding to properties from class with custom behavior

using WPF, c#, VS 2012

Try to implement some custom behaviors for UI with WPF. Currently create class that inherited from Behavior<FrameworkElement>

Idea: create one area on UI for entering name (I used textBox) - another area (Rectangle) - press and see some action with data from prev field.

What was done:

Class for implementing idea (class with Behavior)

class SayHello: Behavior<FrameworkElement>
{
    public string Words { get; set; }
    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonUp += OnMouseClick;
    }
    private void OnMouseClick(object sender, 
                System.Windows.Input.MouseButtonEventArgs e)
    {
        MessageBox.Show(string.Format("hello , {0}", Words));
    }
    protected override void OnDetaching()
    {
        AssociatedObject.MouseLeftButtonUp -= OnMouseClick;
    }        
}

XAML:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    xmlns:local="clr-namespace:CH08.MovingCircle"
    x:Class="CH08.MovingCircle.MainWindow"
    Title="MainWindow" Height="350" Width="525">
<Canvas>
    <Border Canvas.Top="220" BorderBrush="Black" 
            BorderThickness="2">
        <TextBox x:Name="_enteredWords" Width="200"/>
    </Border>

    <Rectangle Stroke="Blue" Canvas.Top="250" Fill="Aquamarine"
               Width="200" Height="50">
        <i:Interaction.Behaviors>
            <local:SayHello 
                Words="{Binding Text, ElementName=_enteredWords}"/>
        </i:Interaction.Behaviors>
    </Rectangle>

</Canvas>

Got error : A 'Binding' cannot be set on the 'Words' property of type 'SayHello'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject...

If i change part of XAML to

        <Rectangle Stroke="Blue" Canvas.Top="250" Fill="Aquamarine"
               Width="200" Height="50">
        <i:Interaction.Behaviors>
            <local:SayHello 
                Words="Adbracadabra"/>
        </i:Interaction.Behaviors>
    </Rectangle>
  • all works (mean just remove binding).

Question: are it's possible to create binding to properties for class with custom behavior? If yes, how can i do this?

EDIT:

As was suggested by vfabre - changed property to dependency property

 public string Words
    {
        get { return (string)GetValue(WordsProperty); }
        set { SetValue(WordsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Words. 
    //This enables animation, styling, binding, etc...
    public static  DependencyProperty WordsProperty =
        DependencyProperty.Register("Words", typeof(string),
        typeof(SayHello), new PropertyMetadata(default(string)));

Result

enter image description here

like image 524
hbk Avatar asked Mar 20 '23 04:03

hbk


1 Answers

Maybe the error message give us the solution. You have to convert your Words property to a dependency propery the following is an example:

public string Words
    {
        get { return (string)GetValue(WordsProperty); }
        set { SetValue(WordsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Words.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WordsProperty =
        DependencyProperty.Register("Words", typeof(string), typeof(SayHello), new PropertyMetadata(default(string)));


    //public string Words { get; set; }

I recommend you to use the code snnipet propdp. Tipping propdp and then tab+tab.

Here you can find more information about dependency properties.

Regards

Edit Changed the default value from string.

like image 192
vfabre Avatar answered Apr 09 '23 16:04

vfabre