我的UserControl
定义如下:
<UserControl x:Class="Speaker.View.Controls.Prompt"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:conv="clr-namespace:Speaker.View.Converters"
mc:Ignorable="d" Height="Auto" Width="300" x:Name="PromptBox">
<UserControl.Resources>
<conv:VisibilityConverter x:Key="VConverter" />
</UserControl.Resources>
<Border Background="White" Padding="10" BorderThickness="1"
BorderBrush="Gray" CornerRadius="10" Height="80"
Visibility="{Binding Path=Show, ElementName=PromptBox,
Converter={StaticResource VConverter}}"
UseLayoutRounding="True">
<Border.Effect>
<DropShadowEffect BlurRadius="20" RenderingBias="Quality" />
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="10" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<TextBox x:Name="InputText" Width="Auto" Height="20"
Text="{Binding Path=InfoText, ElementName=PromptBox, Mode=OneWay}"
Grid.Row="0" BorderThickness="0" Foreground="#FF8D8D8D"
GotFocus="InputText_GotFocus" LostFocus="InputText_LostFocus" />
<Separator Grid.Row="1" />
<Button Content="{Binding Path=ButtonText, ElementName=PromptBox}" Grid.Row="2"
Width="100" Command="{Binding Path=OkCommand, ElementName=PromptBox}" />
</Grid>
</Border>
我想做的是:
当用户点击按钮时,我想运行一些代码(显然是:)) - 这个控件将用于其他一些控件/窗口,我想运行的代码会有所不同,具体取决于在一个scenarion。那么如何使用某个自定义命令绑定此按钮的Command
属性?用法示例:
<ctrls:Prompt Show="{Binding ShouldLogIn}" ButtonText="{Binding LogInText}"
InfoText="{Binding LogInInfo}" OkCommand="what goes here???" Grid.Row="0" Grid.ZIndex="2" />
另外 - 我使用MVVMLight fw跟随MVVM模式,所以我也希望解决方案能够遵循它。
所以问题是 - 如何从提示控件外部绑定到Button.Command?
答案 0 :(得分:3)
我还建议制作一个CustomControl,但是如果你想使用你的UserControl,你需要在你的代码中添加一个DependencyProperty。
public partial class Prompt : UserControl
{
private bool _canExecute;
private EventHandler _canExecuteChanged;
/// <summary>
/// DependencyProperty for the OKCommand property.
/// </summary>
public static readonly DependencyProperty OKCommandProperty = DependencyProperty.Register("OKCommand", typeof(ICommand), typeof(Prompt), new PropertyMetadata(OnOKCommandChanged));
/// <summary>
/// Gets or sets the command to invoke when the OKButton is pressed.
/// </summary>
public ICommand OKCommand
{
get { return (ICommand)GetValue(OKCommandProperty); }
set { SetValue(OKCommandProperty, value); }
}
/// <summary>
/// Gets a value that becomes the return value of
/// System.Windows.UIElement.IsEnabled in derived classes.
/// </summary>
protected override bool IsEnabledCore
{
get { return base.IsEnabledCore && _canExecute; }
}
// Command dependency property change callback.
private static void OnOKCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Prompt p = (Prompt)d;
p.HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue);
}
public Prompt()
{
InitializeComponent();
}
// Add the command.
private void AddCommand(ICommand command)
{
EventHandler handler = new EventHandler(CanExecuteChanged);
_canExecuteChanged = handler;
if (command != null)
command.CanExecuteChanged += _canExecuteChanged;
}
private void CanExecuteChanged(object sender, EventArgs e)
{
if (OKCommand != null)
_canExecute = OKCommand.CanExecute(null);
CoerceValue(UIElement.IsEnabledProperty);
}
// Add a new command to the Command Property.
private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
{
// If oldCommand is not null, then we need to remove the handlers.
if (oldCommand != null)
RemoveCommand(oldCommand);
AddCommand(newCommand);
}
// Remove an old command from the Command Property.
private void RemoveCommand(ICommand command)
{
EventHandler handler = CanExecuteChanged;
command.CanExecuteChanged -= handler;
}
}