Teroman
Teroman

Reputation: 13

Binding on Path.Data Property at a UserControl

I want to make the same as in an previos question from 2011: Should binding to Path.Data property work? but my problem is that i got any other mistake and i don't understand witch one. I'm relay looking since a view days what i am doing wrong, but i must be blind ...

Generic.xaml:

<Style TargetType="{x:Type local:CustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <Path Data="{Binding GeometryData}" x:Name="CurveGraph" Stroke = "Black" StrokeThickness = "2" Grid.RowSpan="4"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

CustomControl.cs:

public class CustomControl : Control    
{

static CustomControl()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
    CustomControl tmp = new CustomControl();
    tmp.Build();
}

public GeometryGroup Build()
{
    var curve = new GeometryGroup();
    curve.Children.Add(new LineGeometry(new Point(0, 0), new Point(20, 20)));
    curve.Children.Add(new LineGeometry(new Point(0, 20), new Point(20, 0)));
    new CustomControl().GeometryData = curve;
    return curve;
}

private GeometryGroup GeometryData
{
    get { return (GeometryGroup)GetValue(GeometryDataProperty); }
    set { SetValue(GeometryDataProperty, value); }
    public static readonly DependencyProperty GeometryDataProperty = DependencyProperty.Register("GeometryData", typeof(GeometryGroup), typeof(CustomControl), new UIPropertyMetadata(new GeometryGroup()));
}

MainWindow.xaml:

<Grid>
    <ctl:CustomControl x:Name="Curve"/>
</Grid>

That's it. The Main Window.xaml.cs only got his constructor. But i really don't know what the problem is. :(

Upvotes: 1

Views: 261

Answers (1)

Clemens
Clemens

Reputation: 128061

It makes no sense to create a temporary CustomControl instance in the (static) class constructor and call the Build method, which sets the GeometryData on yet another temporary instance.

Instead, add an instance constructor that initializes GeometryData on the current instance. Also make GeometryData public.

public class CustomControl : Control
{
    public static readonly DependencyProperty GeometryDataProperty =
        DependencyProperty.Register(
            "GeometryData", typeof(GeometryGroup), typeof(CustomControl));

    public GeometryGroup GeometryData
    {
        get { return (GeometryGroup)GetValue(GeometryDataProperty); }
        set { SetValue(GeometryDataProperty, value); }
    }

    static CustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl),
            new FrameworkPropertyMetadata(typeof(CustomControl)));
    }

    public CustomControl()
    {
        Build();
    }

    public void Build()
    {
        var curve = new GeometryGroup();
        curve.Children.Add(new LineGeometry(new Point(0, 0), new Point(20, 20)));
        curve.Children.Add(new LineGeometry(new Point(0, 20), new Point(20, 0)));
        GeometryData = curve;
    }
}

Besides that you would either use a TemplateBinding in the ControlTemplate

<Path Data="{TemplateBinding GeometryData}" ... />

or specify the binding source like

<Path Data="{Binding GeometryData, RelativeSource={RelativeSource TemplatedParent}}" ... />

Upvotes: 1

Related Questions