WPF中点击含图片的ItemsControl内Label如何仅获取文本内容
WPF ItemsControl点击StackPanel获取文本内容的解决方法
崩溃原因很明确:原来点击的是Label,sender.ToString()能直接拿到绑定的LastName;现在点击的是StackPanel或里面的Image,sender不再是Label,调用ToString()拿到的是控件类型名而非文本,传给AgentSelected方法自然会报错崩溃。下面给几个实用的解决办法:
方法1:直接绑定命令参数(推荐,符合MVVM)
不用依赖sender,直接把数据项的LastName作为命令参数传给ViewModel的方法。在ItemTemplate的StackPanel上绑定命令和参数:
<ItemsControl ItemsSource="{Binding Agents}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <!-- 绑定ItemsControl的DataContext里的命令,参数直接绑LastName --> <StackPanel Command="{Binding DataContext.AgentSelectedCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="{Binding LastName}"> <Image Source="{Binding Avatar}" /> <Label Content="{Binding LastName}" /> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
ViewModel里的AgentSelectedCommand直接接收参数即可,不用再处理sender,不管点StackPanel里的哪个元素,传过去的都是正确的LastName。
方法2:在点击事件里查找内部Label
如果不想改命令逻辑,继续用后台事件的话,可以在StackPanel的点击事件里找到对应的Label,提取文本:
private void StackPanel_Click(object sender, RoutedEventArgs e) { var stackPanel = sender as StackPanel; if (stackPanel == null) return; // 找到StackPanel里的Label(给Label加个Name方便查找) var lastNameLabel = stackPanel.Children.OfType<Label>() .FirstOrDefault(l => l.Name == "LastNameLabel"); if (lastNameLabel != null) { var lastName = lastNameLabel.Content.ToString(); (DataContext as YourViewModel).AgentSelected(lastName); } }
对应的XAML给Label加Name:
<StackPanel Click="StackPanel_Click"> <Image Source="{Binding Avatar}" /> <Label x:Name="LastNameLabel" Content="{Binding LastName}" /> </StackPanel>
方法3:通过DataContext获取数据项
StackPanel的DataContext就是绑定的Agent数据项,直接从这里拿LastName更可靠:
private void StackPanel_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var stackPanel = sender as StackPanel; if (stackPanel == null) return; var agent = stackPanel.DataContext as YourAgentModel; if (agent != null) { (DataContext as YourViewModel).AgentSelected(agent.LastName); e.Handled = true; } }
XAML里绑定预览点击事件:
<StackPanel PreviewMouseLeftButtonDown="StackPanel_PreviewMouseLeftButtonDown"> <Image Source="{Binding Avatar}" /> <Label Content="{Binding LastName}" /> </StackPanel>
内容的提问来源于stack exchange,提问作者Sephystos
相关产品推荐
相关产品推荐

