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検索を行いましたが、答えに最も近いものはここにあります - Passing an enum value as command parameter from XAML残念ながら、Silverlightはx:staticバインディング拡張をサポートしていないため、使用できませんその回答で説明されている正確な手法。

どんな助けでも大歓迎です。

4

4 に答える 4

3

単純なオブジェクト型のようにコマンド パラメータを渡すだけです。次に、列挙型に直接キャストを使用できます。

于 2016-02-29T14:52:18.307 に答える
1

まず、Silverlight で XAML から Enum を直接渡すことができるかどうかわかりません。いずれにせよ、ここに Prism の小さな問題があります。コマンドが 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, }
}

これが私のデリゲート宣言です。Enum自体ではなく、object..の使用に注意してください。また、2 つの異なる方向を公開する ViewModel からプロパティを公開します。

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に直接設定したため、バインディングの状況についてはわかりません。しかし、これはうまくいくはずです。

私の貧弱な英語と雄弁さで申し訳ありませんが、これがあなたを正しい軌道に乗せることを願っています.

于 2009-07-13T05:36:56.593 に答える
1

列挙型のバインドは、WPF でも本当に厄介な操作です。しかし、フレームワークで利用できるエレガントな解決策があるようですCaliburn

ただし、ソリューションはフレームワーク コードでは利用できませんが、LOB Samples. BindableEnumプロジェクトでとBindableEnumCollection<T>クラスを探しCaliburn.Silverlight.ApplicationFrameworkます。

HTH。

于 2009-07-20T04:11:03.017 に答える
0

私自身は試していませんが、文字列のようなものから列挙型までValueConverterを使用することに成功する可能性があります。これは、Silverlightxamlで列挙型を探し回ったときに得た印象でした。

于 2009-05-28T20:41:51.780 に答える