Search code examples
c#wpficommandroutedcommand

Wrapping UserControl functionality in bindable command


Please don't stop yourself from reprimanding me if you find the question too stupid. Hear me please:

  1. I have a custom user control in which I am free to add as many dependency properties as I wish.
  2. The control is basically a data rendering control (I will call it MyControl).
  3. MyControl has a functionality (read method) that enables it to save the data it renders in a disk location.

Ok now this is what I want:

I want a DependencyProperty in MyControl called ExportDataProperty that will wrap this functionality for a button in the xaml to bind to it. Here is some rough code to explain it:

public class MyControl:Control
{

    /// <summary>
    /// <see cref="DependencyProperty"/> for the command that is fired to export the data
    /// </summary>
    public static readonly DependencyProperty ExportDataProperty = DependencyProperty.Register("ExportData", typeof(ICommand), typeof(MyControl), new UIPropertyMetadata(null));

    /// <summary>
    /// Gets or sets the instance of <see cref="ICommand"/> that executes the functionality of exporting.
    /// Please note that this is a synchronous call. It is advised NOT to call this for very big datasets.
    /// </summary>
    public ICommand ExportData
    {
        get { return GetValue(ExportDataProperty) as RoutedCommand; }
        set { SetValue(ExportDataProperty, value); }
    }

    /// <summary>
    /// How do I involve myself with the above command??
    /// how, How, HOw, HOW??
    /// </summary>
    private void ExportMethod()
    {
       string filename = GetFilenameByMagic();
       //Blah blah code to save at filename location.
    }

    private string GetFilenameByMagic()
    {
         return Magic.ReturnFilename();
    }    
}

How do I want to use this?

<Window x:Name="AVeryBigWindow">
  <Window.Resources>
    <ResourceDictionary Source = "pack://application:,,,/FoolsFactory; component/Resources/FunnyColors.xaml"/>
  <Window.Resources>
  <StackPanel>
     <Button Command={Binding ExportData ElementName=myFunnyControl} Content="Click to Export"/>
     <controls:MyControl x:Name="myFunnyControl"/>
  </StackPanel>
</Window >

I am not sure how to wrap the ExportMethod inside the command?

Another worry I have is: what if a consumer of MyControl binds the ExportDataProperty to an ICommand exposed by the ViewModel? I don't want to let that happen.

Am I approaching it the wrong way? Any help will be appreciated.


Solution

  • You can set the command from within the control, and then consume it with your button via binding.

    cs

    public class MyControl:Control
    {
        ...
        public MyControl() 
        {
            ExportData = new DelegateCommand(ExportMethod);
        }
    
        private void ExportMethod()
        {
           string filename = GetFilenameByMagic();
           //Blah blah code to save at filename location.
        }
        ...
    }
    

    xaml

    <local:MyControl x:Name="myControl" />
    <Button Command="{Binding ElementName=myControl, Path=ExportData" />