2011-07-01 38 views
1

我试图在占据相同空间的两个单独的列表框中显示形状。我已将Background设置为Transparent和{x:Null},但鼠标点击仍被顶部列表框捕获,因此我无法从底层ListBox中选择任何图形。两个重叠的ListBoxes。选择问题

下面是一些重现问题的示例代码。

<Grid> 
    <!-- ListBox 1 --> 
    <ListBox Background="{x:Null}"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas Background="{x:Null}"/> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Grid Background="Transparent"> 
        <Ellipse Width="100" Height="100" Stroke="Blue" StrokeThickness="10"/> 
       </Grid> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
     1 
    </ListBox> 

    <!-- ListBox 2 --> 
    <ListBox Background="{x:Null}"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas Background="{x:Null}"/> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
     <ListBox.ItemContainerStyle> 
      <Style TargetType="ListBoxItem"> 
       <Setter Property="Canvas.Left" Value="100"/> 
       <Setter Property="Canvas.Top" Value="100"/> 
      </Style> 
     </ListBox.ItemContainerStyle> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Ellipse Width="100" Height="100" Stroke="Blue" StrokeThickness="10"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
     1 
    </ListBox> 
</Grid> 

这是我如何解决了这个问题,现在,但我比开放更多的其他建议:)我启用hittesting在网格和残疾人它两个ListBox。然后我做了hittesting在事件处理程序,而不是

<Grid MouseDown="Grid_MouseDown" 
     IsHitTestVisible="True" 
     Background="Transparent"> 

    <!-- ListBox 1 --> 
    <ListBox Background="Transparent" 
      IsHitTestVisible="True" 
      ..> 
    </ListBox> 

    <!-- ListBox 2 --> 
    <ListBox Background="Transparent" 
      IsHitTestVisible="True" 
      ..> 
    </ListBox> 
</Grid> 

事件处理程序,并hittesting

private void Grid_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    Grid grid = sender as Grid; 
    Point ptCurrent = e.GetPosition(grid); 
    VisualTreeHelper.HitTest(grid, null, new HitTestResultCallback(HitTestCallback), new PointHitTestParameters(ptCurrent)); 
} 
public HitTestResultBehavior HitTestCallback(HitTestResult htrResult) 
{ 
    ListBoxItem listBoxItem = GetVisualParent<ListBoxItem>(htrResult.VisualHit); 
    if (listBoxItem != null) 
    { 
     listBoxItem.IsSelected = true; 
     return HitTestResultBehavior.Stop; 
    } 
    return HitTestResultBehavior.Continue; 
} 
public T GetVisualParent<T>(object child) where T : Visual 
{ 
    DependencyObject c = child as DependencyObject; 
    while ((c != null) && !(c is T)) 
    { 
     c = VisualTreeHelper.GetParent(c); 
    } 
    return c as T; 
} 
+0

你为什么不有一个列表框中的所有形状?双列表框方法似乎不太可能让你得到你想要的。 – antlersoft

+0

这是我最后一次了......我在地图上显示项目,并且他们根本不共享相同的数据,所以这就是我使用两个ListBox的原因。 ItemsSource是DataTables – George

回答

2

可以通过使用一个CompositeCollection作为项目源多组数据绑定到单个列表框:

<ListBox ...> 
    <ListBox.ItemsSource> 
    <CompositeCollection> 
     <CollectionContainer Collection={Binding ...}" /> 
     <CollectionContainer Collection={Binding ...}" /> 
    </CompositeCollection> 
    </ListBox.ItemsSource> 
</ListBox> 

然后可以使用数据模板来控制不同的数据类型的外观。您可以使用隐式数据模板,也可以使用ItemTemplateSelector

有关使用和结合于CompositeCollection的更多信息,请参阅该资源:How do you bind a CollectionContainer to a collection in a view model?

+0

谢谢,这就是我一直在寻找! – George

0

则可以将列表框绑定到一个可见的变量。通过这种方式,您可以在底部选框处于可选状态时将底部框显示出来,并且当您需要选择顶部框时,顶部框会折叠并签名。

+0

问题是,我的ListBoxes都是可见的,无论如何谢谢 – George