我正在尝试将自定义控件属性绑定到其视图模型的属性及其失败。
我为设置StartDate定义了Dependency属性并更新了PropertyChangeCallback方法
public static readonly DependencyProperty StartDateProperty =
DependencyProperty.Register(StartDatePropertyName,
typeof(DateTime),
typeof(CustomDateTimeControl),
new PropertyMetadata(DateTime.Now.AddYears(-7),
OnStartDatePropertyChanged));
private static void OnStartDatePropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
DateTime dtNewValue = (DateTime)e.NewValue;
if (dtNewValue != DateTime.MinValue)
{
DateTimeControl dtCtrl = d as DateTimeControl;
dtCtrl.StartDate = (DateTime)e.NewValue;
dtCtrl.CoerceValue(StartDateProperty);
}
}
StartDate
属性绑定到其ViewModel的开始日期,因为VM需要执行某些操作,然后将其用于定义自定义控件的下一个可用视图。
<Setter Property="StartDate"
Value="{Binding StartDate,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged}" />
其中定义的DependencyProperty也是从mainWindow视图
设置的<CustomDateTimeLib:CustomDateTimeControl StartDate="01/01/2000 00:00:00" />
绑定仅使用依赖项属性的默认值更新视图模型中的属性,但不使用在MainView中设置的值,即使依赖属性使用MainView中的值进行更新也是如此。
ViewModelLocator类
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<CalendarViewModel>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public CustomDateTimeLib:CustomDateTimeControl CalendarVM
{
get
{
return ServiceLocator.Current.GetInstance<CustomDateTimeControl>();
}
}
}
App.Xaml
<Application x:Class="MvvmCustomTestApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:CustomDateTimeLib.ViewModel"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.galasoft.ch/ignore"
StartupUri="MainWindow.xaml"
mc:Ignorable="d ignore">
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Application.Resources>
CustomDateTimeControl类中的ApplyTemplate覆盖方法
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
CalendarViewModel vm = (CalendarViewModel)this.DataContext;
vm.StartDate = this.StartDate;
}
还定义了StartDate的属性更改回调方法
答案 0 :(得分:1)
如果我理解正确,您有一个要绑定到ViewModel属性的自定义DP,但是您还想从View中为此属性设置默认值。
对于MVVM或者当您使用绑定时,这不是一个理想的设置。 MVVM应该具有所有逻辑,包括&#34; X&#34;的默认值。在ViewModel图层中,View图层仅用于为用户提供与ViewModel(数据)图层交互的可视方式。
所以你的解决方案是:
.strings
)或FallbackValue(适用于DateTime
)如果使用MVVM,选项1是最佳解决方案,因为应该在ViewModel中设置自定义DefaultValue之类的东西,而不是View。
如果此默认值特定于此UserControl,则选项2最佳,并且在使用此控件的任何时候都是相同的。
如果您确实坚持从视图层设置默认值,则选项3,4和5适用于任何原因。使用哪一个取决于您的情况。
假设您使用#1,我希望您的最终XAML看起来像这样:
DateTime?
那就是它。
上面的XAML代码中的<!-- assumes DataContext is of type DateTimeCtrlVM via inheritance or direct binding -->
<CustomDateTimeLib:CustomDateTimeControl StartDate="{Binding StartDate}" />
实际上会导致以下情况发生:
<Setter>
到VM属性,这意味着数据将仅从Target(Control)流向Source(ViewModel),因此1/1/2000的值将持久保存到您的VM 因此,摆脱将属性绑定为OneWayToSource的Setter,使用上面显示的XAML绑定,并在ViewModel中设置默认值,它应该可以工作。