0

我正在使用 WPF 和 MVVM Light 框架。在我的项目中,我有GameViewModel一个关联视图,它充当我游戏的主屏幕(这不是我的主 ViewModel)。在 GameView 中,我想在网格中的某个位置动态显示其他用户控件,这些用户控件由按钮单击或类似性质的东西触发。我不完全确定该怎么做。我考虑过使用辅助 ViewModelLocator 或类似的东西(我根本不确定如何去做),但在我深入研究之前,我想我会在这里问一下,看看是否有更实用的方法做这个。

假设单击了一个按钮,UserControl1 显示在网格上的 3、3 处,然后单击另一个按钮并且 UserControl2 显示在同一位置。这基本上就是我想要完成的。虽然这不是必须的,但我想使用尽可能多的 XAML 和尽可能少的代码隐藏,但是任何以 MVVM 友好的方式完成工作的东西对我来说都非常好。您可以提供的任何建议将不胜感激。我猜这个解决方案可能比我想象的要容易得多……通常是这样。

4

2 回答 2

2

我在最近的一个项目中使用的一个想法是将元素的 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>

流体按钮类;

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 回答