从UserControl获取ListBox DataContext

时间:2014-10-22 15:24:09

标签: xaml windows-phone-8

我有一个UserControl,里面有一个按钮。 UserControl的DataContext是我的模型之一,所以我可以绑定它。但是,对于按钮,我希望能够从我的viewmodel调用方法。 ListBox的DataContext就是这个ViewModel。

因为我的ContextMenu也需要相同的DataContext,我就这样绑定了它们:

Command="{Binding Path=DataContext.AttendEventCommand, ElementName=EventListBox}"

调用EventListBox元素并使用其DataContext调用AttendEventCommand。但是,我想从UserControl上的按钮调用AttendEventCommand。我尝试以同样的方式做到这一点,但遗憾的是它没有用。

我的数据上下文设置如下:

DataContext="{Binding Path=EventList, Source={StaticResource Locator}}

我的列表框代码:

<ListBox x:Name="EventListBox" ItemsSource="{Binding Occurrences}" Margin="0,50,0,0" >
    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <uctl:EventListItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="auto" Height="auto">
                                    <toolkit:ContextMenuService.ContextMenu>
                                        <toolkit:ContextMenu IsZoomEnabled="True" x:Name="ContextMenu">
                                            <toolkit:MenuItem x:Name="Going" Header="{Binding AttendingText}" Command="{Binding Path=DataContext.AttendEventCommand, ElementName=EventListBox}" CommandParameter="{Binding}"/>
                                        </toolkit:ContextMenu>
                                    </toolkit:ContextMenuService.ContextMenu>
                                </uctl:EventListItem>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
</ListBox>

我的UserControl按钮:

<Button Grid.RowSpan="3" Grid.Column="5" Opacity="0" Command="{Binding Path=DataContext.AttendEventCommand, ElementName=EventListBox}" CommandParameter="{Binding}"/>

2 个答案:

答案 0 :(得分:1)

DataContext的{​​{1}}将成为EventListItem的模型,因为它是ItemsSource的一部分。所以你必须明确地设置它。

有关我将用作解决方案的一些代码,请参阅How to implement a navigation button


让我们假设您的自定义DataTemplate非常基本:

UserControl

其中SimpleCommand是您要在顶视图模型中调用的命令。

然后您必须将<UserControl> <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}"> <Button Command="{Binding DataContext.SimpleCommand}" CommandParameter="1"></Button> </Grid> </UserControl> 更改为

DataTemplate

您的<DataTemplate> <Grid> <uctl:EventListItem DataContext="{Binding ElementName=myListBox}"/> <!-- more xaml --> </Grid> </DataTemplate> 应该按原样运作。


<toolkit:ContextMenu>的执行功能处设置一个断点,你会看到它会得到 每次都打到那里。

ICommand

答案 1 :(得分:1)

我相信你的问题并不是你想要做的不行;相反,你的设计似乎是错误的。

你现在拥有的是这样的: 您的WindowDataContextListBoxListBox有一个ItemsSource,我们假设它是IEnumerable<Occurrence>

ListBox中每件商品的外观均为EventListItem,其中UserControl至少包含一个Button

您希望此Button的{​​{1}}在Command的{​​{1}}上调用方法。

这最后一句错了。项目具有按钮的事实意味着它执行与项目相关的操作,而不是窗口内容。如果不是这样,那么可能应该重新考虑窗口和列表框项目的可视化设计。

如果按钮实际上影响了该项目,那么您不应该在Window的{​​{1}}上调用方法,而是在项目的DataContext上调用方法。< / p>

解决方案是将模型对象Window包装在自己的视图模型类中。我们称之为DataContext。您DataContext的{​​{1}}将是Occurrence的某种形式。因为它是一个视图模型,所以允许实现OccurrenceViewModel方法,然后可以以某种方式操纵ListBox,直接或最好通过将其传递给实现用例的某个类。 / p>