Silverlight 3/Prism - 将枚举值作为命令参数传递

5

我正在尝试使用Prism和MVVM模式开发应用程序。在我的UI中,我定义了一个“上一页”和“下一页”的按钮。为了在调用Web服务时使用,我定义了一个枚举类型,它将告诉我需要遍历的方向。因此,在这种情况下,按钮直接映射到枚举值。枚举定义非常简单,如下所示:

namespace CodeExpert.Book.Helpers
{
    public enum BookDirection { Previous = -1, NotSet = 0, Next = 1, }
}

我已经在我的ViewModel中定义了命令和委托,并正确地分配了属性。相关代码如下:

public DelegateCommand PreviousNextCommand { get; set; }

public IndexEntriesViewModel(GlobalVariables globalVariable, IndexEntryOperations currentOperator)
{
    //a bunch of initialization code.
    InitializeCommands();
}

void InitializeCommands()
{
    PreviousNextCommand =
        new DelegateCommand(OnPreviousNextCommandExecute);
}

private void OnPreviousNextCommandExecute(BookDirection parameter)
{

    //Code to process based on BookDirection
}

因此,根据这个配置,我想将一个BookDirection枚举值传递给CommandParameter。然而,我无法正确设置XAML。以下是我认为最正确的XAML:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 mc:Ignorable="d"
                 x:Class="CodeExpert.Book.Views.Index"
                 d:DesignWidth="1024"
                 d:DesignHeight="768"
                 xmlns:helpers="clr-namespace:CodeExpert.Book.Helpers"
                 xmlns:command="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"
                 xmlns:common="clr-namespace:System.Windows;assembly=System.Windows.Controls"
                 xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
                 xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
                 xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input">

    <Button x:Name="ButtonPrevious"
              HorizontalAlignment="Left"
              Margin="2,1,0,1"
              Width="25"
              Content="<"
              Grid.Column="1"
              Grid.Row="1"
              Height="20"
              command:Click.Command="{Binding Path=CurrentIndexViewModel.PreviousNextCommand}">
        <command:Click.CommandParameter>
            <helpers:BookDirection.Previous />
        </command:Click.CommandParameter>
    </Button>

</UserControl>

我在枚举类型的BookDirection上没有获得智能提示,并在设计和编译时得到一个错误,说“类型‘BookDirection’不包含‘Previous’的定义”。有没有办法传递该枚举,或者我可能遗漏了什么?现在我将参数类型设置为string而非BookDirection,这样可以工作,但需要解析文本,代码显得冗杂。我进行了一些Google搜索,最接近答案的是这里 - 从XAML传递枚举值作为命令参数不幸的是,Silverlight不支持x:static绑定扩展,因此我无法使用该答案中描述的确切技术。任何帮助都将不胜感激。
4个回答

3

只需像简单对象类型一样传递命令参数。然后,您可以直接将其强制转换为枚举类型。


1
首先,我不确定您是否可以直接从Silverlight的XAML中传递Enum。无论如何,在Prism中存在一个小问题。请注意,Command在CommandParameter之前被设置,当内部设置命令时,Prism会调用UpdateEnabledState(),它在您的DelegateCommand上调用CanExecute(object parameter),并将CommandParameter(请记住尚未设置)传递给它。
下面是Prism中DelegateCommand.cs的基本代码。
 bool ICommand.CanExecute(object parameter)
    {
        return CanExecute((T)parameter);
    }

由于此时参数为“null”,所以强制转换会抛出异常。以下是我解决这个问题的方法。

您的枚举。

namespace CodeExpert.Book.Helpers
{
    public enum BookDirection { Previous = -1, NotSet = 0, Next = 1, }
}

这是我的委托声明,请注意使用对象而不是枚举本身。我还从ViewModel公开属性,将公开2个不同的方向。
public DelegateCommand<object> PreviousNextCommand { get; set; }

public BookDirection Previous { get { return BookDirection.Previous; }}
public BookDirection Next { get { return BookDirection.Next; }}

现在在你的OnPreviousNextCommandExecute方法中,确保你接收到一个对象并将其强制转换回正确的枚举类型。

private void OnPreviousNextCommandExecute(object parameter)
{

    BookDirection direction = (BookDirection)parameter;

    //Code to process based on BookDirection
}

并且在XAML中直接绑定到公开的BookDirection属性。

<Button Content="Next"  Commands:Click.Command="{Binding PreviousNextCommand}" Commands:Click.CommandParameter="{Binding Next}" />
<Button Content="Previous" Commands:Click.Command="{Binding PreviousNextCommand}" Commands:Click.CommandParameter="{Binding Previous}" />

我不确定你的绑定情况,因为在我的情况下,我直接将我的DataContext设置为ViewModel。但这对你应该有效。

抱歉我的英语和修辞能力不好,希望这能让你走上正确的轨道。


Stan,你的英语和口才都很好。实际上,我已经把这个项目放在后炉子里一段时间了,但是预计本周会再次开始着手处理。我将尝试你的技巧。 - Steve Brouillard
嗨,史蒂夫,我想知道你有没有试过这个。我很好奇它是否对你有用。 - Stan R.

1

绑定枚举在编程中是一个麻烦的操作,即使在WPF中也是如此。但是似乎有一种优雅的解决方案可用于Caliburn框架。

然而,这个解决方案并不在框架代码中,而是在它的LOB Samples中。请查找Caliburn.Silverlight.ApplicationFramework项目中的BindableEnumBindableEnumCollection<T>类。

希望对你有所帮助。


0

我自己没有尝试过,但你可以尝试使用一个ValueConverter将类似字符串的值转换为你的枚举类型。这是我在寻找Silverlight xaml中的枚举时得到的印象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接