gpt4 book ai didi

c# - 将命令绑定(bind)到模板化用户控件

转载 作者:太空宇宙 更新时间:2023-11-03 21:41:52 24 4
gpt4 key购买 nike

我是 WPF 的新手,但由于一本关于该主题的好书,当然还有像这样的网站上的高质量帖子,我在短时间内取得了很大进步。但是,现在我遇到了一些我似乎可以通过这些方法弄清楚的事情,所以我发布了我的第一个问题。

我在资源字典中有一个 ControlTemplate,我将其应用于多个 UserControl View 。该模板提供了一个简单的叠加边框和两个按钮:保存和取消。模板化用户控件包含各种文本框等,并根据上下文绑定(bind)到某些 ViewModel。当我在某些 View 中使用/声明 UserControl 时,我试图弄清楚如何将命令绑定(bind)到保存/取消按钮。这是可能的,还是我做错了什么?

一、模板:

<ControlTemplate x:Key="OverlayEditorDialog"
TargetType="ContentControl">
<Grid>
<Border HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="DarkGray"
Opacity=".7"/>
<Border HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="DarkGray">
<Grid>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0"/>
<Grid Grid.Row="1"
Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column="1"
Content="Cancel"
***Command="{Binding CancelCommand}}"**
/>
<Button Grid.Column="0"
Content="Save"
***Command="{Binding Path=SaveCommand}"***/>
</Grid>
</Grid>
</Border>
</Grid>
</ControlTemplate>

模板依次用于 CustomerEditorOverlay 用户控件

<UserControl x:Class="GarazhApp.View.CustomerEditorOverlay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<UserControl.Resources>
<ResourceDictionary Source="Dictionary1.xaml"/>
</UserControl.Resources>
<ContentControl Template="{StaticResource ResourceKey=OverlayEditorDialog}">
<Grid Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<SomeElement/>
<SomeOtherElement/>
</Grid>
</ContentControl>

...最后,用户控件用作 View 的一部分,如下所示:

<local:CustomerEditorOverlay Visibility="{Binding Path=CustomerViewModel.ViewMode, Converter={StaticResource myConverter}, FallbackValue=Collapsed}"
d:IsHidden="True" />

最佳答案

因此,根据我从一个我从事了半年的项目中学到的知识,我们有了一个可行的模式。

假设您有一堆模态窗口,它们在应用程序中都应用了相同的样式。为了在每个 View 上都有 Save 和 Cancel 按钮,用于所有模式窗口的 UserControl 有几个依赖属性。此外,我们为您的命令(例如 OnSaveCommand、OnCancelCommand、CanExecuteSaveCommand、CanExecuteCancelCommand)指定虚拟方法,并将命令本身指定为由您的 View 继承的基础 ViewModel 中的属性。

最终,我们只需执行以下操作即可创建新的模态窗口:

<my:YourBaseView x:class="MyFirstView" xmlns:whatever="whatever" [...]>
<my:YourBaseView.PrimaryButton>
<Button Content="Save" Command="{Binding SaveCommand}" />
</my:YourBaseView.PrimaryButton>

<!-- some content -->
</my:YourBaseView>

附带代码隐藏:

public class MyFirstView : YourBaseView
{
[Import] /* using MEF, but you can also do MvvmLight or whatever */
public MyFirstViewModel ViewModel { /* based on datacontext */ }
}

还有一个 ViewModel:

public class MyFirstViewModel : ViewModelBase
{
public override OnSaveCommand(object commandParameter)
{
/* do something on save */
}
}

此 UserControl 的模板指定网格布局中的 ContentControls,其中 Content 属性绑定(bind)到 PrimaryButton 和 SecondaryButton。当然,模式的内容存储在 UserControl 的 Content 属性中,并显示在 ContentPresenter 中。

<Style TargetType="{x:Type my:YourBaseView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type my:YourBaseView}">
<Grid>
<!-- ignoring layout stuff -->
<ContentControl Content="{TemplateBinding Content}" />
<ContentControl Content="{TemplateBinding PrimaryButton}" />
<ContentControl Content="{TemplateBinding SecondaryButton}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

用户控件代码:

public class YourBaseView : UserControl
{
public static readonly DependencyProperty PrimaryButtonProperty =
DependencyProperty.Register("PrimaryButton", typeof(Button), typeof(YourBaseView), new PropertyMetadata(null));
public Button PrimaryButton
{
get { return (Button)GetValue(PrimaryButtonProperty); }
set { SetValue(PrimaryButtonProperty, value); }
}

/* and so on */
}

当然,您可以更改模板化 View 的每个实例的样式。我们只是碰巧坚持使用一种基本样式。

TL;DR edit:我可能有点过火了,因为我认为您只需要了解每次创建新的时通过 XAML 设置的公开 Button 类型的依赖属性覆盖。那,或者您可能可以使用 RelativeSource 返回到可视化树,例如 {Binding DataContext.SaveCommand, RelativeSource={RelativeSource AncestorType={x:Type MyView}}} 但它有点脏.

关于c# - 将命令绑定(bind)到模板化用户控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18971867/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com