Catel WPF UserControl 无法从依赖项中获取值 属性

Catel WPF UserControl can`t get value from dependency property

我有自定义用户控件,它必须更改 window 中的某些布尔变量并从某些绑定中获取值。但是当我第一次尝试获取它的值时,它等于默认值 - 空。当我采取行动时,效果很好。

<catel:UserControl x:Class="App.Shell.Controls.ToggleButton"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:catel="http://catel.codeplex.com"
                   xmlns:debug="clr-namespace:System.Diagnostics;assembly=System">
    <!-- Content -->
    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Width" Value="37" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Label
                                Margin="0"
                                Padding="0"
                                HorizontalContentAlignment="Center"
                                VerticalContentAlignment="Center"
                                Background="#010000"
                                Foreground="#FEFEFF"
                                FontSize="12">
                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                            </Label>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsTurnedOn}" Value="True">
                        <Setter Property="Content" Value="Turn off" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsTurnedOn}" Value="False">
                        <Setter Property="Content" Value="Turn on" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>

        <Button>
            <Button.InputBindings>
                <MouseBinding Command="{Binding ToggleCmd}" MouseAction="LeftDoubleClick" />
            </Button.InputBindings>
        </Button>
    </Grid>
</catel:UserControl>

使用 catel viewmodel

namespace App.Shell.Controls
{
    using Catel.Data;
    using Catel.MVVM;
    using System;
    using System.Windows.Input;

    /// <summary>
    /// UserControl view model.
    /// </summary>
    public class ToggleButtonViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ToggleButtonViewModel"/> class.
        /// </summary>
        public ToggleButtonViewModel()
        {
            ToggleCmd = new Command(OnToggleCmdExecute);
        }

        /// <summary>
        /// Gets the title of the view model.
        /// </summary>
        /// <value>The title.</value>
        public override string Title { get { return "ToggleButton"; } }

        public Command ToggleCmd { get; private set; }
        private void OnToggleCmdExecute()
        {
            IsTurnedOn = !IsTurnedOn;
        }

        public bool IsTurnedOn
        {
            get { return GetValue<bool>(IsTurnedOnProperty); }
            set { SetValue(IsTurnedOnProperty, value); }
        }
        public static readonly PropertyData IsTurnedOnProperty = RegisterProperty("IsTurnedOn", typeof(bool), setParent: false, createDefaultValue: null);
        // TODO: Register models with the vmpropmodel codesnippet
        // TODO: Register view model properties with the vmprop or vmpropviewmodeltomodel codesnippets
        // TODO: Register commands with the vmcommand or vmcommandwithcanexecute codesnippets
    }
}

和代码隐藏

namespace App.Shell.Controls
{
using Catel.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using Catel.MVVM.Views;
using System;
using Catel.MVVM;

/// <summary>
/// Interaction logic for ToggleButton.xaml.
/// </summary>
public partial class ToggleButton : UserControl
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ToggleButton"/> class.
    /// </summary>
    public ToggleButton()
    {
        InitializeComponent();
    }

    [ViewToViewModel(MappingType = ViewToViewModelMappingType.TwoWayViewWins)]
    public bool IsTurnedOn
    {
        get { return (bool)GetValue(IsTurnedOnProperty); }
        set { SetValue(IsTurnedOnProperty, value); }
    }
    public static readonly DependencyProperty IsTurnedOnProperty =
        DependencyProperty.Register("IsTurnedOn", typeof(bool), typeof(ToggleButton), new PropertyMetadata(null));
}

}

我将该控件插入到我的目录中 window

<ctrls:ToggleButton IsTurnedOn="{Binding Path=IndividualSpeechTimerState, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" />

当我第一次尝试从 UserControl 获取 属性 IsTurnedOn 时,它等于默认值。

由于您定义了 [ViewToViewModel(MappingType = ViewToViewModelMappingType.TwoWayViewWins)],它总是会写入视图的第一次 属性。这允许您在外部绑定此值。

确保在依赖项 属性 定义中设置有效值(例如 true 或 false)。

    [ViewToViewModel(MappingType = ViewToViewModelMappingType.ViewModelToView)]
    public bool IsTurnedOn
    {
        get { return (bool)GetValue(IsTurnedOnProperty); }
        set { SetValue(IsTurnedOnProperty, value); }
    }
    public static readonly DependencyProperty IsTurnedOnProperty =
        DependencyProperty.Register("IsTurnedOn", typeof(bool), typeof(ToggleButton), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsTurnedOnChanged));

    private static void OnIsTurnedOnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var btn = d as ToggleButton;
        var vm = btn.ViewModel as ToggleButtonViewModel;
        if(vm.IsTurnedOn != btn.IsTurnedOn)
            vm.IsTurnedOn = btn.IsTurnedOn;
    }