如何将我的IntemsControl列表中的命令绑定到我的主ViewModel?

时间:2014-07-22 02:03:23

标签: c# wpf mvvm

如何将命令从我的IntemsControl列表绑定到我的主ViewModel?

<Window x:Class="MemoryGame.MainWindow"
        ...
        DataContext="{Binding Main, Source={StaticResource Locator}}">
    <Window.Resources>
        <me:ColorConverter x:Key="ColorConverter"/>
    </Window.Resources>
    <Grid x:Name="LayoutRoot" Background="#FF44494D">
        <ItemsControl ItemsSource="{Binding GameBoard.CardList}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Rectangle x:Name="Card01" Fill="{Binding Converter={StaticResource ColorConverter}}" Height="100" Width="100" Margin="10,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Stroke="Black">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Click">
                                <i:InvokeCommandAction Command="{Binding SelectCardCommand, ???????????}" CommandParameter="{Binding Name, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Rectangle}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Rectangle>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        ...

SelectCardCommand在我的主窗口ViewModel中定义。我已经尝试添加RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = Window}但它不起作用。

----编辑更多信息----

在我的DataContext ViewModel中,我有这个:

public class MainViewModel : ViewModelBase
{
    private RelayCommand<string> _selectCardCommand;
    public RelayCommand<string> SelectCardCommand
    {
        get
        {
            return _selectCardCommand;
        }
    }

    public MainViewModel()
    {
        _selectCardCommand = new RelayCommand<string>((s) => DoSelectCardCommand(s));
        // GameBoard = new Board();
        // this.StartGame();
    }

    private void DoSelectCardCommand(string card)
    {
        // Code here
    }
}

1 个答案:

答案 0 :(得分:2)

你可以使用两种方法

使用RelativeSource

<i:EventTrigger EventName="Click">
    <i:InvokeCommandAction Command="{Binding DataContext.SelectCardCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}" 
                           CommandParameter="{Binding Name, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Rectangle}}"/>
</i:EventTrigger>

或使用ElementName

<i:EventTrigger EventName="Click">
    <i:InvokeCommandAction Command="{Binding DataContext.SelectCardCommand, ElementName=LayoutRoot}" 
                           CommandParameter="{Binding Name, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Rectangle}}"/>
</i:EventTrigger>

修改

执行代码后我意识到原因,因为矩形没有任何名为Click的事件,因此它不会绑定,但是你可以绑定到UIElement.MouseDown

或者我想出了一个不同的方法来解决你的问题。

我稍微修改模板以使用Button并根据需要模板化按钮,并且还更改了ItemsPanelTemplate,使其看起来更像是一个记忆游戏

    <ItemsControl ItemsSource="{Binding GameBoard.CardList}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid IsItemsHost="True" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Command="{Binding DataContext.SelectCardCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}"
                        CommandParameter="{Binding}">
                    <Button.Template>
                        <ControlTemplate>
                            <Rectangle Fill="{Binding Converter={StaticResource ColorConverter}}"
                                       Height="100"
                                       Width="100"
                                       Margin="10,10,0,0"
                                       Stroke="Black">
                            </Rectangle>
                        </ControlTemplate>
                    </Button.Template>
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

命令

    #region SelectCardCommand

    public RelayCommand<Card> SelectCardCommand { get; private set; }

    #endregion

    public MainViewModel()
    {
        SelectCardCommand = new RelayCommand<Card>((s) => DoSelectCardCommand(s));
        GameBoard = new Board();
        this.StartGame();
    }

    private void DoSelectCardCommand(Card card)
    {
        if (card != null)
            card.Upside = true;
    }

这将有助于您删除int.Parse(card.Substring(4,2));和其他字符串操作