2013-01-08 5 views
5

私はListBoxのアイテムのリストを表示するSilverlightアプリケーションを持っています。リストボックスのボタンを正しく使用するにはitemtemplate/datatemplate?

<Style x:Key="navigationItemContainerStyle" TargetType="ListBoxItem"> 
    <Setter Property="Margin" Value="5,3"/> 
    <Setter Property="FontSize" Value="16"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate> 
       <Grid Cursor="Hand"> 
        <VisualStateManager.VisualStateGroups> 
         <!-- code omitted --!> 
        </VisualStateManager.VisualStateGroups> 
        <Border x:Name="contentBorder" 
          Background="{StaticResource navigationHighlightBrush}" 
          CornerRadius="3" 
          Opacity="0"/> 
        <ContentControl x:Name="content" 
            Margin="10,5" 
            Content="{Binding}" 
            Foreground="DarkGray"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

スタイルは非常に簡単です:各項目はので、私はこのようになりますItemContainerStyleプロパティに適用されたスタイルを持っている私のアプリケーションの異なる「ページ」を表しています。 ListBoxItemのビジュアル状態が「選択済み」に等しい場合は、単にBorderと表示されます。項目が「選択済み」状態のときにForegroundプロパティを変更できるようにするため、内容はContentControlによってホストされていることに注意してください。

下記のスクリーンショットで見ることができるように、これは見事に動作します:今、私は私が持っていたアイデアは、それぞれの内容を設定しますDataTemplateを作成することでしたので、選択した項目は、ナビゲーションを呼び出したい

enter image description here

HyperLinkButtonのアイテム:

<DataTemplate x:Key="navigationListBoxItemTemplate"> 
    <HyperlinkButton Content="{Binding}" 
        Background="Transparent"/> 
</DataTemplate> 

さて、これはそれがContentControlなく、のコンテンツですItemTemplateホストとして動作しません。だからを代わりに使用するようにListBoxItemテンプレートを更新しなければならなかった。

<ContentPresenter x:Name="content" Margin="10,5"/> 

私は今、次のような結果を得る:私は今、もはや選択されているHyperLinkButtonListBoxItemをクリックすると

enter image description here

(私はHyperLinkButton外でちょうどクリックするとListBoxItemが選択された状態になるが) 。私が本当に欲しいのは、HyperLinkButtonがクリックされたときにListBoxItemが選択されることです。 HyperLinkButtonには選択の概念がないので、ListBoxItemIsSelectedプロパティにバインドすることはできません。

注:実際のナビゲーションは完全に動作しますが、問題は純粋にListBoxItemsの外観です。

だから私の質問は以下のとおりです。HyperLinkButtonがクリックされた場合、ListBoxItemは最初の画像のように、選択になるよう

  1. は、私はそれを作ることはできますか?
  2. HyperLinkButtonのフォアグラウンドを変更する方法も必要です。これは、ContentControlからContentPresenterを交換してアイテムテンプレートでこれ以上行われないためです。

注:私はおそらく私のViewModelにListBoxSelectedItemプロパティを結合し、各ListBoxItemが主催HyperLinkButtonを持っている必要性を否定するが、私はかどうかを知るに興味があっナビゲーションを処理することで、この問題を解決することができスタイルとテンプレートを使用して私の望む結果を達成することは可能です。

更新

私はこれを試してみて、解決するために物事のカップルを試してみましたが、これまでのところ成功していません。私が試した最初の試みは、DataTemplateHyperLinkButtonコントロールに新しいスタイルを適用することでした。これは本質的にすべてのデフォルトのルックアンドフィールをコントロールから削除しますが、私のアプリケーションは上記のように動作します。

私が試したもう1つのことは、IsHitTestVisibleプロパティをfalseに設定していたことです。これにより、HyperLinkbuttonを「スルー」してListBoxItemを選択することができますが、ナビゲーションがもう呼び出されなくなりました。

+0

こんにちは、listBox_SelectionChanged()イベントハンドラ内でNavigationService.Navigate(Uri)メソッドを使用できますか? – prthrokz

+0

@prthrokz - ナビゲーションメソッドを呼び出す際に問題はありません。私の問題は純粋に 'ListBoxItem'のプレゼンテーションです。 –

+0

HyperLinkBut​​tonの追加を実質的に省略することができるという私の意図は、投稿から理解したことは、ナビゲーションを呼び出すために切り替えなければならなかったからです。 – prthrokz

答えて

0

ListBoxItemは、MouseLeftButtonDownイベントをHandledとしてマークしているため、ListBoxItemは選択されていません。したがって、必要なイベントは、親のListBoxItemまでバブルアップしません。

明らかに、あなたのListBoxItemはクリックからフォーカスを得ています(私はそれが最終イメージの境界線であると見なします)。

ListBoxItemには、Selectionを処理するための標準のLeftMouseButtonDownイベントハンドラがあり、フォーカスの設定に対処するためにAddHandlerを呼び出す必要があります。


あなたがそうのように、イベント用に独自のハンドラを追加することにより、類似した何かを達成することができます

は、これを取り付け...最後のパラメータを扱うイベントを処理するハンドラを指示

listboxitem.AddHandler(UIElement.MouseLeftButtonDownEvent, new System.Windows.Input.MouseButtonEventHandler(MyMouseLeftButtonDownEventHandler), true); 

を私はあなたに任せますが、行動を使うことはおそらく最も単純です。あなたはButtonから型を派生させ、Visual Treeを見て、ListBoxItemを探して選択することができます。可能性は無限です。

+0

事実は、イベントが既にボタンによって処理されていたという事実は明らかだったはずです。私の質問で述べたように、私は実際には代わりの解決策を用意していましたが、情報は依然として有益でした。ありがとうございました。 –