C# 在xaml中单击内部列表时,要点击事件的参数为空

C# 在xaml中单击内部列表时,要点击事件的参数为空,c#,xaml,windows-phone-8,caliburn.micro,C#,Xaml,Windows Phone 8,Caliburn.micro,我对XAML和Caliburn.Micro有点陌生。我遇到了一个“奇怪”的问题 我正在用Caliburn.Micro制作一个WindowsPhone8应用程序,我有一个带有项目的列表框,其中包括另一个带有一些细节行的内部列表框 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,5,12,5" > <ListBox x:Name="CurrentStunts"

我对XAML和Caliburn.Micro有点陌生。我遇到了一个“奇怪”的问题

我正在用Caliburn.Micro制作一个WindowsPhone8应用程序,我有一个带有项目的列表框,其中包括另一个带有一些细节行的内部列表框

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,5,12,5" >
        <ListBox x:Name="CurrentStunts"
                 cal:Message.Attach="[Tap]=[Action OpenStuntOnWeb(CurrentStunts.SelectedItem)]">
            <ListBox.ItemTemplate>
                <DataTemplate>
                        <Grid DataContext="{Binding}" Background="#FFCC00" Margin="0,10,0,10">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="45"/>
                            <ColumnDefinition Width="*" MinWidth="345"/>
                            <ColumnDefinition Width="40"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <StackPanel Grid.Column="0">
                             <StackPanel.Background>
                                <ImageBrush ImageSource="{Binding StuntDetails.Channel,Converter={StaticResource ChannelIconConverter}}"  Stretch="Uniform" AlignmentY="Top"/>
                             </StackPanel.Background>
                        </StackPanel>
                        <StackPanel Grid.Column="1" Orientation="Vertical">
                            <TextBlock Text="{Binding Title}" Foreground="#CC0000" TextWrapping="Wrap"/>
                            <TextBlock Text="{Binding SubTitle}" Foreground="#336699" TextWrapping="Wrap"/>
                            <ListBox ItemsSource="{Binding DetailLines}">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding}" Foreground="#336699" FontSize="14" TextWrapping="Wrap"/>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>

                        </StackPanel>
                        <StackPanel Grid.Column="2" Orientation="Vertical">
                            <TextBlock Text="{Binding StuntDetails.NewPrice}" Foreground="#CC0000" />
                                <Grid HorizontalAlignment="Left" VerticalAlignment="Top">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="1*"/>
                                        <RowDefinition Height="1*"/>
                                    </Grid.RowDefinitions>
                                    <TextBlock HorizontalAlignment="Left" Text="{Binding StuntDetails.OldPrice}" VerticalAlignment="Top" Grid.RowSpan="2" Foreground="#336699"/>
                                    <Border BorderThickness="0,0,0,1" BorderBrush="#336699" >
                                    </Border>
                                </Grid>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
问题是,启动应用程序并单击内部列表框(详细信息行)的任意位置时,方法public void OpenStuntOnWeb(StuntSummary currentItem)中的参数“currentItem”为null。当点击外部列表框CurrentStunts(如标题或副标题)时,它工作正常,并填写参数

更奇怪的是,当您单击外部列表框,然后单击内部列表框时,它也可以正常工作,并且填充了参数。只有在第一次单击内部列表框时,“currentItem”才为空


我被困在这一点上,因此任何帮助都将不胜感激。

这里的问题是您正在响应
点击事件。点击事件最有可能在设置了
SelectedItem
后广播,但由于您点击的是内部控件,因此您没有从外部列表框中选择任何项目-您仍然会收到
tap
,但不会收到
SelectedItem
(您可能需要尝试
SelectionChanged

点击内部列表框时,外部列表框会响应
点击
事件,但由于您尚未点击外部列表框,因此不会设置选择,因此会将空值传递给方法

编辑:

使用CM
SpecialValues
和我在这里发布的代码确定:

您可以提取最初调用事件的项的
DataContext
ListBoxItem
启动事件并将其气泡化到
ListBox
中,触发它的
Tap
事件,因此路由事件的
OriginalSource
将是
ListBoxItem
希望-无论哪种方式,该项都应该具有正确的
DataContext
!)

那你就可以用

cal:Message.Attach=“[Event Tap]=[Action DoSomething($originalsourcedatacontext)]”

因此,总结如下:

将此添加到CM引导程序(
Configure
method通常是最佳位置)


您好,谢谢您的回复。我尝试了一下,但没有运气。现在它只会在单击外部列表框时打开。以前,单击外部列表框后,我可以按“上一步”并在内部列表框中按另一个项目,这会起作用。此外,SelectionChanged带来了另一个问题:当人们单击它时,他们会按“上一步”并再次单击它,该事件在逻辑上不会触发。您可以发布一些布局的屏幕截图并进一步详细说明预期的行为吗?我正在尝试了解您真正希望它做什么,并且由于您绑定到
ItemsSource
每个项都已包含在子控件的
DataContext
中,因此您可以移动
Tap
事件降低或获取点击项的数据上下文?可能可以使用CMs
特殊值来获取点击项的数据上下文-我之前用一个例子回答了另一个问题,让我看看是否可以找到它。在这里找到它-信息:-如果要使用它并从t获取
数据上下文
你可以提取绑定项并自动传递给方法的动作发送者-我将编辑答案bitHey Charleh。非常感谢你的帮助!同时我意识到我是个白痴:)我有一个纯文本的项子列表,还有一个专门用来保存我的视图对象的对象。所以,我没有做的只是将所有文本串在我的视图对象的1“details”属性中,并用一个textblock显示它。我将把你的回答标记为答案,它可能会帮助有更好理由拥有子列表的人:)再次感谢!
        public void OpenStuntOnWeb(StuntSummary currentItem)
    {
        if (currentItem != null)
        {
            var uri = stuntManager.BuildStuntLink(currentItem.StuntDetails);

            var webBrowserTask = new WebBrowserTask();
            webBrowserTask.Uri = uri;
            webBrowserTask.Show();
        }
    }
MessageBinder.SpecialValues.Add("$originalsourcedatacontext", (context) =>
{
    if (context.EventArgs is EventArgs)
    {          
        var e = context.EventArgs as EventArgs;

        // If the control is a FrameworkElement it will have a DataContext which contains the bound item
        var fe = e.OriginalSource as FrameworkElement;

        if (fe != null)
            return fe.DataContext;
    }

    return null;
});