简体   繁体   中英

Binding UserControls DependencyProperty to ViewModels Property

I am having a UserControl called ChartControl which displays a chart. To determine that the ChartControl is initialized, it needs to run a command which is defined inside a ViewModel called DiagnosisViewModel . The Command gets instantiated inside this ViewModel. After the ChartControl is loaded, it should execute the Command, but at this point, it is still null. It seems like that the Binding of the Command does not work as expected. Let the explain it better with code:

ChartControl.xaml

<UserControl x:Class="GoBeyond.Ui.Controls.Charts.ChartControl"
             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"
             mc:Ignorable="d"
             x:Name="ThisChartControl"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
</UserControl>

ChartControl.xaml.cs

public partial class ChartControl : INotifyPropertyChanged
{
    public ChartControl()
    {
        Loaded += OnLoaded;
    }

    public static readonly DependencyProperty ReadyCommandProperty = DependencyProperty.Register(
            nameof(ReadyCommand), typeof(ICommand), typeof(ChartControl), new PropertyMetadata((o, args) =>
            {
                Debug.WriteLine("Ready Command updated");
            }));

    public ICommand ReadyCommand
    {
        get { return (ICommand)GetValue(ReadyCommandProperty); }
        set { SetValue(ReadyCommandProperty, value); }
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        // Initialize the ChartControl with some values
        ...

        // At this point the Command is ALWAYS null
        ReadyCommand?.Execute(this);
    }
}

ChartControl defined in DiagnosisView.xaml

<charts:ChartControl ReadyCommand="{Binding FrequencyReadyCommand}" />

DiagnosisViewModel

public class DiagnosisViewModel : ViewModelBase // ViewModelBase derives from Prisms BindableBase
{
    public DiagnosisViewModel(...)
    {
        FrequencyReadyCommand = new DelegateCommand<ChartControl>(OnFrequencyChartReady);
    }

    public ICommand FrequencyReadyCommand
    {
        get => _frequencyReadyCommand;
        set => SetProperty(ref _frequencyReadyCommand, value);
    }
}

The getter of FrequencyReadyCommand seems never gets called, so I think there is any issue with my binding here. I tried with multiple Modes and UpdateSourceTriggers, but I cannot find out, what I am doing wrong here

You should invoke the command in the dependency property callback instead of handling the Loaded event:

public static readonly DependencyProperty ReadyCommandProperty = DependencyProperty.Register(
        nameof(ReadyCommand), typeof(ICommand), typeof(ChartControl), new PropertyMetadata((o, args) =>
        {
            ChartControl chartControl = (ChartControl)o;
            chartControl.ReadyCommand?.Execute(null);
        }));

Unlike the Loaded event, the callback is always invoked after the property has been set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM