Search code examples
c#xamlmvvmdata-bindingwindows-phone

DataContext is not getting set inside Custom Button with Path Data


Hello I am trying to make a custom Button with PathData inside it. So far I have managed to view the Path inside it. But my Button is not taking MVVM Commands.

Custom Button XAML

<Button x:Class="My_Class.CustomControls.MyButtonWithPath"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
    <Grid>
        <Path  Data="{Binding}" Name="path"/>
    </Grid>
</Button>

Button Code Behind

public partial class MyButtonWithPath : Button
{
    public MyButtonWithPath()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private static string _pathDatay;
    public string PathDatay
    {
        get { return _pathDatay; }
        set { _pathDatay = value; }
    }

    public static readonly DependencyProperty PathDataProperty =
        DependencyProperty.Register("PathDatay", typeof(string), typeof(MyButtonWithPath), new PropertyMetadata(pathDataCallback));

    private static void pathDataCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        _pathDatay = (string)e.NewValue;
    }
}

Usage In XAML

<converters:KeyToValueConverter x:Key="conv"/>
<custom:MyButtonWithPath PathDatay="{Binding ConverterParameter=tv, Converter={StaticResource conv}}" />

Converter

 public class KeyToValueConverter : IValueConverter
 {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            return Utils.GetPathData(parameter.ToString());
        }
        catch (Exception c)
        {
            throw c;
        }

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }
}

Utils Class

public static string GetPathData(string key)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();

        dictionary.Add("tv", "etc etc etc......");
        return dictionary[key];
    }

The Problem

Whenever I am writing a Command in the Usage of the Button, it shows a not found error as it looks for the command inside my Custom Button NOT my MainViewModel(FYI I have a ViewModel named MainViewModel where I will put the Command related codes)

My Guess

I am setting the DataContext of the Button to itself with this "this.DataContext=this;" But if I omit this line then the Path does not show. Please guide me to set these things correctly

Solution

Given below


Solution

  • You are right, this.DataContext=this; this line is the problem.
    You typically dont use databinding for setting the look of the custom control. Instead you should set the Name of Path and set its Data property on initialization. You can do this by overriiding OnApplyTemplate:

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        Path p = GetTemplateChild("path") as Path;
        p.Data = ...
    }