0

私は WPF と MVVM Light フレームワークを使用しています。私のプロジェクトにはGameViewModel、ゲームのメイン画面として機能する関連付けられたビューがあります (これはメインの ViewModel ではありません)。GameView 内で、グリッド内の特定の場所で、ボタンのクリックなどによってトリガーされる他の UserControls を動的に表示したいと考えています。これについてどうすればよいか完全にはわかりません。セカンダリViewModelLocatorまたは同様のものを使用することを考えました(これを行う方法がまったくわかりません)が、それに飛び込む前に、ここで質問して、より実用的な方法があるかどうかを確認しますこれを行う。

ボタンをクリックすると、UserControl1 がグリッドの 3、3 に表示され、別のボタンがクリックされると、UserControl2 が同じ場所に表示されます。これは本質的に私が達成しようとしていることです。必須ではありませんが、できるだけ多くの XAML を使用し、コード ビハインドをできるだけ少なくしたいと考えていますが、MVVM に適した方法で作業を完了させるものはすべて、私にとっては問題なく機能します。アドバイスをいただければ幸いです。解決策は、おそらく私が考えているよりもはるかに簡単だと思います... 通常はそうです。

4

2 に答える 2

2

最近のプロジェクトで使用した 1 つのアイデアは、要素の Visibility プロパティを ViewModel の Visibility プロパティにバインドすることです。その後、ViewModel ですべての表示ロジックを処理できます。

Visibility="{Binding ElementVisibility}"

次に、ViewModel には次のようなプロパティがあります。

public const string ElementVisibilityPropertyname = "ElementVisibility";
private Visibility _elementVisibility = Visibility.Collapsed;
public Visibility ElementVisibility
{
    get
    {
        return _elementVisibility;
    }
    set
    {
        if (_elementVisibility== value)
        {
            return;
        }

        RaisePropertyChanging(ElementVisibilityPropertyname );
        _elementVisibility= value;
        RaisePropertyChanged(ElementVisibilityPropertyname );
    }
}

Button では、次のように Command プロパティをバインドします。

Command="{Binding ShowElement}"

そして、ViewModel で RelayCommand を提供します。

private RelayCommand _showElement;
public RelayCommand ShowElement
{
    get
    {
        return _showElement?? (_showElement= new RelayCommand(() =>
                             {
                                 this.ElementVisibility = Visibility.Visible;
                             ));
    }
}

うまくいけば、これはあなたが探している方向にあなたを導きます!

于 2013-06-11T23:14:19.000 に答える
1

ここで非常に類似したことについてブログ投稿を作成しました。

http://pjgcreations.blogspot.co.uk/2013/03/wpf-programmatically-adding-buttons.html

以下では、Canvas、ItemPresenter、および DataTemplate を使用して、実行時に ViewModel から設定されたボタンを表示します。

XAML:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Canvas x:Name="MyCanvas">
        <ItemsControl ItemsSource="{Binding MyButtons}" Height="237" Width="507">
            <ItemsControl.ItemsPanel >
                <ItemsPanelTemplate>
                    <Canvas IsItemsHost="true"></Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Margin="{Binding ControlMargin}" Content="{Binding Content}" Command="{Binding DataContext.ButtonCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding ProductId}"></Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Canvas>
</Window>

Fluid ボタン クラス。

Public Class FluidButton

    Public Property Content As String
    Public Property LeftPos As Double
    Public Property TopPos As Double
    Public Property ProductId As Double

    'Returns the Control Margin, using the Class Properties
    Public ReadOnly Property ControlMargin As Thickness
        Get
            Return New Thickness With {.Left = LeftPos, .Top = TopPos}
        End Get
    End Property

End Class

ViewModel のプロパティ。

'Our Collection of Buttons or Products
Public Property MyButtons As ObservableCollection(Of FluidButton)

'Used to expose the Button Pressed Execute Commands to the UI for Binding
Public Property ButtonCommand As DelegateCommand

いくつかのボタンを追加するには;

MyButtons = New ObservableCollection(Of FluidButton)

MyButtons.Add(New FluidButton With {.Content = "Test1", .LeftPos = 0, .TopPos = 20, .ProductId = 1})
MyButtons.Add(New FluidButton With {.Content = "Test2", .LeftPos = 40, .TopPos = 30, .ProductId = 2})
MyButtons.Add(New FluidButton With {.Content = "Test3", .LeftPos = 80, .TopPos = 40, .ProductId = 3})
MyButtons.Add(New FluidButton With {.Content = "Test4", .LeftPos = 120, .TopPos = 50, .ProductId = 4})
MyButtons.Add(New FluidButton With {.Content = "Test5", .LeftPos = 160, .TopPos = 60, .ProductId = 5})

ニーズに合わせてこれを簡単に変更できると確信しています

于 2013-06-11T23:37:11.210 に答える