2013-05-03 53 views
0

我对XAML和Caliburn.Micro有点新鲜。我遇到了一个“怪异”的问题。当点击xaml中的内部列表时,点击事件的参数为空

我正在用Caliburn.Micro制作一个Windows Phone 8应用程序,并且我有一个带有项目的ListBox,然后包含另一个带有一些细节行的内部ListBox。

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

中的代码的视图模型与CAL:Message.Attach = “[TAP] = [动作OpenStuntOnWeb(CurrentStunts.SelectedItem)]” 是以下内容:

 public void OpenStuntOnWeb(StuntSummary currentItem) 
    { 
     if (currentItem != null) 
     { 
      var uri = stuntManager.BuildStuntLink(currentItem.StuntDetails); 

      var webBrowserTask = new WebBrowserTask(); 
      webBrowserTask.Uri = uri; 
      webBrowserTask.Show(); 
     } 
    } 

问题引导时被应用程序并在内部ListBox(DetailLines)上的任意位置单击方法public void OpenStuntOnWeb(StuntSummary currentItem)中的参数“currentItem”为null。当点击外部ListBox CurrentStunts(例如Title或SubTitle)时,它工作正常并且参数被填充。

更奇怪的是当您单击外部ListBox然后单击内部ListBox时它也可以正常工作和参数填充,只有当在内部列表框说:“CURRENTITEM”第一击为空。

我被困在这个,所以任何帮助将不胜感激。

回答

0

这里的问题是,你响应Tap事件。水龙头事件是SelectedItem设置之后,最有可能的广播,但是因为你敲击你是不是从外部列表框中选择任何项目的内部控制 - 你仍然得到Tap但不是SelectedItem(你可能想尝试SelectionChanged代替)。

当在内部列表框上点击时,外部列表框正在响应Tap事件,但由于您没有点击外部,所以未设置选择,因此将空值传递给该方法。

编辑:

好使用CM SpecialValues和我张贴在这里的代码:RadMenu and RadMenuItem Caliburn.Micro

您可以提取最初调用该事件的项目的DataContext(该ListBoxItem启动事件和气泡时,到ListBox这是它的Tap事件,所以路由事件的OriginalSource将是ListBoxItem有希望 - 无论哪种方式该项目应该有权利!)

然后,你可以使用

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

因此,要总结:

一下添加到CM的引导程序(Configure方法通常是最好的地方)

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; 
}); 
+0

你好,谢谢为答复。我给了它一个镜头,但没有运气。现在只有在单击外部列表框时才会打开它。以前,一旦外部列表框被点击,我可以按回来,甚至在内部列表框中按下另一个项目,它会工作。SelectionChanged也提出了另一个问题:当用户点击它时,他们会再次按下并再次单击它,事件在逻辑上不会触发。 – user2346814 2013-05-03 14:26:00

+0

你可以发布一些布局的截图,并详细说明预期的行为?我试图弄清楚你真正想要做什么,并且由于你绑定到了'ItemsSource',所以每个项目都已经包含在子控件的'DataContext'中,所以你可以将'Tap'事件移动到更低向下,或采取tapped项目的datacontext?可能可以使用CM的'SpecialValues'来获取挖掘项目的数据上下文 - 我之前用一个例子回答了另一个问题,让我看看我能否找到它 – Charleh 2013-05-03 14:38:49

+0

在这里找到它 - 信息:http://stackoverflow.com/questions/15913380/radmenu-and-radmenuitem-caliburn-micro/15921851#15921851 - 如果你要使用它并从动作发送者那里获取'DataContext',你可以提取绑定项并自动传递给方法 - 我会编辑答案 – Charleh 2013-05-03 14:46:43