2016-09-05 46 views
0

我有自定义用户控件,它必须在窗口中更改一些布尔变量并从某些绑定中获取值。但是,当我第一次尝试获取值等于默认值 - null。当我采取行动时,它的效果很好。Catel WPF UserControl无法从依赖属性中获取值

<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视图模型

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)); 
} 

}

我插入控制我的catel窗口

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

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

+0

Null对于bool不是有效的值。也许这是导致DependencyProperty的一些问题? – ibebbs

+0

不,我很努力。绑定不设置值为dp只是使用默认值always –

回答

0
[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; 
    } 
0

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

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

+0

是的,我需要外部绑定。但值等于vm的默认值 –