Question

I am developing a WPF application using the MVVM pattern. I have a window with two controls: a user control and a button. The button's Command property is bound to a RelayCommand (from MVVM Light) on the user control's VM. Here is the xaml:

<local:TraceChartView x:Name="chartView"/>
<Button Content="Copy To Clipboard" 
        Command="{Binding ElementName=chartView, 
                          Path=DataContext.CopyToClipboardCommand}"/>   

So clicking the "Copy To Clipboard" button executes the CopyToClipboardCommand RelayCommand in the TraceChartView's VM. This works fine, but it requires me to use a complicated mechanism to get the command from the VM to the TraceChartView's code behind where it can actually implement the action. It seems like I should be able to implement something like a dependency property in the TraceChartView's code behind and bind the button action directly to it, i.e.:

<local:TraceChartView x:Name="chartView"/>
<Button Content="Copy To Clipboard" 
        Command="{Binding ElementName=chartView, 
                          Path=CopyToClipboardCommand}"/>   

I tried this and a bunch of variations, but no luck. Is there any way to do this?

Edit:

I tried doing this with a Dependency Property. Here is the TraceChartView code behind:

private static readonly DependencyProperty CopyToClipboardCommandProperty =   
    DependencyProperty.Register("CopyToClipboardCommand",
                                typeof(ICommand),
                                typeof(TraceChartView),
                                new FrameworkPropertyMetadata(null, OnSomePropertyChanged));

private static void OnSomePropertyChanged(DependencyObject d, 
                                          DependencyPropertyChangedEventArgs e)
{
    // never called
}

public ICommand CopyToClipboardCommand
{
    set
    {
        this.SetValue(CopyToClipboardCommandProperty, value);
    }
    get
    {
        return (ICommand)this.GetValue(CopyToClipboardCommandProperty);
    }
}

I tried binding like this:

<local:TraceChartView x:Name="chartView"/>
<Button Content="Copy To Clipboard" 
        Command="{Binding ElementName=chartView, 
                          Path=CopyToClipboardCommand}"/>   

This doesn't produce any console errors, but my callback is never called.

Was it helpful?

Solution

The problem with my code is that I created a dependency property, but I never set the property to anything. When I did this in the constructor, it worked:

public TraceChartView()
{
    InitializeComponent();

    CopyToClipboardCommand = new RelayCommand(DoCopyToClipboard);
}

For my implementation, I don't really need a dependency property, and the whole thing can be implemented with a single line in the code behind:

public RelayCommand CopyToClipboardCommand { get { return new RelayCommand(DoCopyToClipboard); } }

with this xaml:

<local:TraceChartView x:Name="chartView"/>
<Button Content="Copy To Clipboard" 
    Command="{Binding ElementName=chartView, 
                      Path=CopyToClipboardCommand}"/>

I hope that this will help some other WPF beginner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top