使用 MVVM 和 Catel 自定义用户控件
Custom Usercontrol with MVVM and Catel
我创建了一个自定义用户控件,它由一个带有选定项的自动完成框组成...直到现在我已经以我不喜欢的方式实现它...我的意思是我有一个 XAML 视图,一个视图模型,在视图模型中,我从存储过程加载数据。
由于自动完成框是第三方用户控件,我已将其添加到 XAML 视图中,而不是定义为自定义用户控件。这样做的最佳做法是什么?
我认为我现在使用 Catel 作为 MVVM 框架这一事实是无关紧要的..
谢谢
更新 #1
我的用户控件需要有一些通过 XAML 传递的属性,例如 (LoadDefaultValue)
<views:PortfolioChooserView x:Name="PortfolioChooserView" DataContext="{Binding Model.PortfolioModel}" Height="25" LoadDefaultValue="True" Width="150" />
为了实现这样的场景,我必须在我的 PortfolioChooserView 中定义一个依赖项 属性,定义为
public bool LoadDefaultValue
{
get { return (bool)GetValue(LoadDefaultValueProperty); }
set { SetValue(LoadDefaultValueProperty, value); }
}
public static readonly DependencyProperty LoadDefaultValueProperty = DependencyProperty.Register(
"LoadDefaultValue", typeof(bool), typeof(PortfolioChooserView), new PropertyMetadata(default(bool)));
因为如果我只在 Viewmodel 中定义它,我将无法设置它。
奇怪的是,为了将它传递给视图模型,我不得不做这样的把戏
public PortfolioChooserView()
{
InitializeComponent();
if (!isFirstLoad) return;
Focusable = true;
PortfolioCompleteBox.AllowDrop = true;
PortfolioCompleteBox.Focus();
DragDropManager.AddPreviewDragOverHandler(PortfolioCompleteBox, OnElementDragOver);
DragDropManager.AddDropHandler(PortfolioCompleteBox, OnElementDrop);
DataContextChanged += PortfolioChooserView_DataContextChanged;
isFirstLoad = false;
}
void PortfolioChooserView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var dataContext = DataContext as PortfolioModel;
if (dataContext != null)
{
dataContext.LoadDefaultValue = LoadDefaultValue;
dataContext.AllowNull = AllowNull;
//var converter = new PortfolioConverter();
//var portfolio = (Portfolio) converter.Convert(SelectedItem, null, null, CultureInfo.CurrentCulture);
//dataContext.SelectedItem = portfolio;
}
}
但我真的不喜欢使用 DataContextChanged 事件...您看到更好的方法了吗?
感谢
更新#2
我把这个放在一起,因为这是一个相关的问题...
在某些视图模型上,我使用了 DeferValidationUntilFirstSaveCall = true;在构造函数中禁用加载时的验证,但我的自定义用户控件显示红色边框...我应该怎么做才能将该信息传播到嵌套的用户控件?
再次感谢
有关大量示例,请参阅 Orc.Controls。这是一个开源库,其中包含许多使用 Catel 构建的用户控件,甚至还有一个带有自动完成框的控件。
我创建了一个自定义用户控件,它由一个带有选定项的自动完成框组成...直到现在我已经以我不喜欢的方式实现它...我的意思是我有一个 XAML 视图,一个视图模型,在视图模型中,我从存储过程加载数据。 由于自动完成框是第三方用户控件,我已将其添加到 XAML 视图中,而不是定义为自定义用户控件。这样做的最佳做法是什么? 我认为我现在使用 Catel 作为 MVVM 框架这一事实是无关紧要的..
谢谢
更新 #1
我的用户控件需要有一些通过 XAML 传递的属性,例如 (LoadDefaultValue)
<views:PortfolioChooserView x:Name="PortfolioChooserView" DataContext="{Binding Model.PortfolioModel}" Height="25" LoadDefaultValue="True" Width="150" />
为了实现这样的场景,我必须在我的 PortfolioChooserView 中定义一个依赖项 属性,定义为
public bool LoadDefaultValue
{
get { return (bool)GetValue(LoadDefaultValueProperty); }
set { SetValue(LoadDefaultValueProperty, value); }
}
public static readonly DependencyProperty LoadDefaultValueProperty = DependencyProperty.Register(
"LoadDefaultValue", typeof(bool), typeof(PortfolioChooserView), new PropertyMetadata(default(bool)));
因为如果我只在 Viewmodel 中定义它,我将无法设置它。
奇怪的是,为了将它传递给视图模型,我不得不做这样的把戏
public PortfolioChooserView()
{
InitializeComponent();
if (!isFirstLoad) return;
Focusable = true;
PortfolioCompleteBox.AllowDrop = true;
PortfolioCompleteBox.Focus();
DragDropManager.AddPreviewDragOverHandler(PortfolioCompleteBox, OnElementDragOver);
DragDropManager.AddDropHandler(PortfolioCompleteBox, OnElementDrop);
DataContextChanged += PortfolioChooserView_DataContextChanged;
isFirstLoad = false;
}
void PortfolioChooserView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var dataContext = DataContext as PortfolioModel;
if (dataContext != null)
{
dataContext.LoadDefaultValue = LoadDefaultValue;
dataContext.AllowNull = AllowNull;
//var converter = new PortfolioConverter();
//var portfolio = (Portfolio) converter.Convert(SelectedItem, null, null, CultureInfo.CurrentCulture);
//dataContext.SelectedItem = portfolio;
}
}
但我真的不喜欢使用 DataContextChanged 事件...您看到更好的方法了吗? 感谢
更新#2
我把这个放在一起,因为这是一个相关的问题... 在某些视图模型上,我使用了 DeferValidationUntilFirstSaveCall = true;在构造函数中禁用加载时的验证,但我的自定义用户控件显示红色边框...我应该怎么做才能将该信息传播到嵌套的用户控件?
再次感谢
有关大量示例,请参阅 Orc.Controls。这是一个开源库,其中包含许多使用 Catel 构建的用户控件,甚至还有一个带有自动完成框的控件。