绑定依赖项属性 - 在自定义用户控件中设置,在viewmodel中获取

时间:2016-08-08 09:00:39

标签: c# wpf xaml data-binding dependency-properties

目的是在自定义UserControl中实例化一个对象,然后从viewmodel访问该实例。但是以下方法不起作用,viewmodel中的UpRatings属性为null。

具有依赖属性的自定义UserControl

public partial class Scale:UserControl
{

    public Scale()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty MouseRatingsProperty = 
        DependencyProperty.Register(
        "MouseRatings",
        typeof(IObservable<double>),
        typeof(Scale));

    public IObservable<double> MouseRatings
    {
        get
        {
            return (IObservable<double>)GetValue(MouseRatingsProperty);
        }
        set
        {
            SetValue(MouseRatingsProperty, value);                
        }
    }

    // requires System.Reactive NuGet
    private ISubject<double> _mouseRatings = new Subject<double>();

    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
        // _mouseRatings is the object instance I need to access in the viewmodel
        MouseRatings = _mouseRatings;
    }
}

视图

<StackPanel>
    <scale:Scale MouseRatings="{Binding Path=UpRatings, Mode=TwoWay}"/>
</StackPanel>

视图模型

// requires Prism.Wpf NuGet
public class MyViewModel : BindableBase
{
    public IObservable<double> UpRatings { get; set; }

    // called after the DataContext is set, so the UpRatings binding should work here by now
    // see https://github.com/PrismLibrary/Prism/blob/master/Documentation/WPF/60-Navigation.md
    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        // but UpRatings is unfortunately null here
        Trace.WriteLine(UpRatings == null ? "null" : "not null");
    }

}

请注意,DataContext不是直接在自定义用户控件上设置,而是直接设置为她的父级(我可以在自定义用户控件中确认)。

1 个答案:

答案 0 :(得分:0)

当MouseRatings = _mouseRatings时它开始工作;稍后调用如下,而MouseRatings如果将其设置为OnInitialized则因某些神秘原因而失去其值。

public Scale()
    {
        InitializeComponent();
        IsVisibleChanged += Scale_IsVisibleChanged;
    }

private void Scale_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (IsVisible)
        {
            MouseRatings = _mouseRatings;
        }
    }

它也可以在UserControl Loaded事件中设置它,但是viewmodel必须等待额外的时间才能访问该对象。