C# 在xaml中单击内部列表时,要点击事件的参数为空
我对XAML和Caliburn.Micro有点陌生。我遇到了一个“奇怪”的问题 我正在用Caliburn.Micro制作一个WindowsPhone8应用程序,我有一个带有项目的列表框,其中包括另一个带有一些细节行的内部列表框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"
<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
)
点击内部列表框时,外部列表框会响应点击
事件,但由于您尚未点击外部列表框,因此不会设置选择,因此会将空值传递给方法
编辑:
使用CMSpecialValues
和我在这里发布的代码确定:
您可以提取最初调用事件的项的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;
});