WP7:为什么ListBox.ItemsPanel会破坏我的ElementName数据绑定?

时间:2011-01-09 16:49:52

标签: c# silverlight data-binding windows-phone-7 mvvm-light

我有一个绑定到整数列表的Windows Phone 7 ListBox。我使用默认的MVVM Light模板,因此有一个ViewModel类包含数据和一个简单的RelayCommand。这是ListBox:

<ListBox ItemsSource="{Binding MyData}">
    <ListBox.ItemTemplate>
        <DataTemplate>                        
            <Button Content="{Binding}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <cmd:EventToCommand Command="{Binding ElementName=ContentGrid, Path=DataContext.TestCommand}"
                                            CommandParameter="{Binding}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这将显示按钮内的整数垂直列表。如果单击其中任何一个,将执行以下命令代码并显示弹出窗口:new RelayCommand<int>(i => MessageBox.Show("Test" + i));

但是,如果我只是添加以下XAML以更改为水平列表,则数据绑定将失败。单击按钮时没有任何反应,并且没有错误消息写入“输出”窗口。

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" />
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

我为EventToCommand尝试了一些其他类型的绑定。例如,将我的ViewModel指定为静态资源。它有效,但不如上面的例子理想。

为什么ItemsPanel会破坏数据绑定?

1 个答案:

答案 0 :(得分:2)

这是Silverlight 3的已知问题。要解决此问题,请将DataTemplate包裹在UserControl

    <UserControl x:Class="SilverlightApplication.MyUserControl">
        <Button Content="{Binding}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <cmd:EventToCommand Command="{Binding ElementName=ContentGrid, Path=DataContext.TestCommand}"
                                        CommandParameter="{Binding}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </UserControl>

然后使用它:

<ListBox ItemsSource="{Binding MyData}">
    <ListBox.ItemTemplate>
        <DataTemplate>                        
            <local:MyUserControl />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>