2011-07-01 3 views
1

私は同じスペースを占める2つの別々のリストボックスに図形を表示しようとしています。私は透明と{x:Null}の両方にバックグラウンドを設定しましたが、マウスクリックはまだ一番上のリストボックスに取り込まれているので、基になるListBoxからシェイプを選択することはできません。重複する2つのリストボックス。選択問題

問題を再現するサンプルコードです。

<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有効になっており、両方のリストボックスにとって無効になっています。それから私は、イベントハンドラの代わりに

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

イベントハンドラとあなたが可視性変数に、あなたのリストボックスをバインドすることができ

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

あなたは、単一のリストボックス内のすべての形状を持っていないのはなぜ? 2つのリストボックスのアプローチは、あなたが望むものを得ることは本当にありそうもないようです。 – antlersoft

+0

これは私の最後のものです。私はマップの上にアイテムを表示しています、そして、彼らは全く同じデータを共有しないので、私は2つのリストボックスを使用しています。 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

をhittestingでhittestingをしました。この方法では、下のボックスを選択する必要があるときに下のボックスが選択され、上のスペースが折りたたまれ、ビザが選択される状況にあるときに下のボックスを表示させることができます。

+0

問題は、両方のリストボックスが常に表示されていることです。ありがとうございました – George

関連する問題