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;
}
我有自定义用户控件,它必须更改 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;
}