vanao veneri
vanao veneri

Reputation: 1054

Bind Property of a custom class to View

I have created a UserControl and in code-behind have added a new class:

Public WithEvents Fridolin As New Frog With {.Location = New Point(11, 22)}
Public Class Frog
    Implements INotifyPropertyChanged

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    Private Sub NotifyPropertyChanged(Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    Dim _location As Point
    Property Location As Point
        Get
            Return _location
        End Get
        Set(value As Point)
            _location = value
            NotifyPropertyChanged("Location")
        End Set
    End Property
End Class

As you can see there is also an Instance of Frog. Now, in my XAML there is a Path object which I would like to bind to the Location property of object "Fridolin".

Here is my XAML

<UserControl x:Class="ucFrogup"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:app="clr-namespace:resi_estimate"
         mc:Ignorable="d" 
         DataContext="{Binding RelativeSource={RelativeSource Self}}"
         d:DesignHeight="360" d:DesignWidth="640">
<UserControl.Resources>
    <ResourceDictionary>
        <StreamGeometry x:Key="ProtoLeaf" >m 451.45 512 c 17.06 0 30.43 -13.86 30.43 -31.56 V 31.55 C 481.87 13.86 468.51 0 451.44 0 A 32.94 32.94 0 0 0 434.99 4.52 L 46.29 229 c -10.13 5.85 -16.18 16 -16.18 27 0 11 6 21.2 16.18 27 l 388.7 224.48 a 32.92 32.92 0 0 0 16.45 4.52 z</StreamGeometry>
        <StreamGeometry x:Key="ProtoFrog">m 51.45 512 c 17.06 0 30.43 -13.86 30.43 -31.56 V 31.55 C 481.87 13.86 468.51 0 451.44 0 A 32.94 32.94 0 0 0 434.99 4.52 L 46.29 229 c -10.13 5.85 -16.18 16 -16.18 27 0 11 6 21.2 16.18 27 l 388.7 224.48 a 32.92 32.92 0 0 0 16.45 4.52 z</StreamGeometry>
    </ResourceDictionary>
</UserControl.Resources>
<Grid>
    <Viewbox Margin="97,10,10,10">

        <Canvas x:Name="Pond" Background="#FF58CFF1" Margin="4" Height="360" Width="640">


            <Path x:Name="Froggy" Height="80" Width="80" Canvas.Left="{Binding Source=Fridolin, Path=Location.X}" Canvas.Top="{Binding Source=Fridolin, Path=Location.Y}" Stretch="Uniform" Fill="#FF43B231" Data="{DynamicResource ProtoFrog}"/>

        </Canvas>
    </Viewbox>
    <Button x:Name="btnGo" Content="Go" HorizontalAlignment="Left" VerticalAlignment="Top" Height="34" Width="78" ></Button>
</Grid>

What am I missing? I get this error message btw:

System.Windows.Data Error: 40 : BindingExpression path error: 'Location' property not found on 'object' ''String' (HashCode=-1218894399)'. BindingExpression:Path=Location.Y; DataItem='String' (HashCode=-1218894399); target element is 'Path' (Name='Froggy'); target property is 'Top' (type 'Double')

Upvotes: 0

Views: 58

Answers (1)

Troels Larsen
Troels Larsen

Reputation: 4631

I'm not sure what is going on in your code behind, but based on what I know, do the following:

  1. Change your bindings to: Canvas.Left="{Binding Path=Fridolin.Location.X}"
  2. In the constructor of your code behind, assign your DataContext as itself. I work in C#, so bear with me here: this.DataContext = this;

Step 2 may be optional, as I can't recall whether or not the DataContext is already assigned to itself.

This will set the DataContext for all your bindings to the ucFrogup object itself, thus enabling you to binding without specifying a source. Sources are used for binding to (other) UI elements, not properties.

I recommend anyone wanting to do WPF to read up on the MVVM pattern. It makes bindings much simpler and easier to read.

Upvotes: 1

Related Questions