2012-02-20 8 views
0

多くのOptions (Menu.Options)が含まれているMenuオブジェクト(DataContextとして設定されています)には、​​と多くのOptions (Option.Options)が含まれています。コレクションはすべてタイプObservableCollection<T>です。WP7 ListPicker - DataSourceから生成されたモデルで選択された項目にマークを付ける方法は?

メニューはXMLファイルから読み込まれるため、オプションと値の量はさまざまです。私は何とかデータバインドされたモデルの現在の選択をマークしたいSelectionChangedイベント、上の方法ListPicker_SelectionChangedを持って

<ListBox ItemsSource="{Binding Path=Options}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <!-- Title --> 
       <TextBlock Text="{Binding Path=Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" /> 
       <!-- Selection --> 
       <toolkit:ListPicker ItemsSource="{Binding Path=Options}" SelectionChanged="ListPicker_SelectionChanged"> 
        <toolkit:ListPicker.ItemTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding Path=Name}" /> 
         </DataTemplate> 
        </toolkit:ListPicker.ItemTemplate> 
        <toolkit:ListPicker.FullModeItemTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding Path=Name}" /> 
         </DataTemplate> 
        </toolkit:ListPicker.FullModeItemTemplate> 
       </toolkit:ListPicker> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

する視覚化を支援するために、ここでは関係XAMLです。私は、各ListPickerが実行時に生成されるので、メソッドに供給されたパラメータだけを使用してそれを行う必要があります。だから私は実際のコントロール名を指定することはできません(私が知っている限り)。

私は2つの可能なオプションを参照することができます:Selectedを持っているために)私はそのListPicker

2のために最後に選択した項目への参照を置くことができますMenu.Option内部CurrentSelectionを、持っているために

1) Option.Optionの属性ここでは、新しい要素が選択されたときにすべての要素が選択解除されていることを確認しています。

私はオブジェクトツリーsenderをブラウズしようとしましたが、見つけたものはItemsHostのようにアクセスできません(プライベート/保護されています)。

解決策はありますか?

答えて

0

オプション1は、ListPicker.SelectedItemでTwoWayバインディングを使用する方が優れています。

<phone:PhoneApplicationPage 
    x:Class="StackOverflowWP7.SO9369491" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" 
    xmlns:local="clr-namespace:StackOverflowWP7.SO9369491_" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    SupportedOrientations="Portrait" Orientation="Portrait" 
    shell:SystemTray.IsVisible="True"> 
    <phone:PhoneApplicationPage.DataContext> 
     <local:Menu> 
      <local:Menu.Options> 
       <local:Option Description="Size"> 
        <local:Option.Options> 
         <local:Option local:Description="Large" /> 
         <local:Option local:Description="Regular" /> 
        </local:Option.Options> 
        <local:Option.CurrentSelection> 
         <local:Option local:Description="Regular" /> 
        </local:Option.CurrentSelection> 
       </local:Option> 
      </local:Menu.Options> 
     </local:Menu> 
    </phone:PhoneApplicationPage.DataContext> 
    <!--LayoutRoot is the root grid where all page content is placed--> 
    <Grid x:Name="LayoutRoot" Background="Transparent"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 

     <!--TitlePanel contains the name of the application and page title--> 
     <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> 
      <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> 
      <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> 
     </StackPanel> 

     <!--ContentPanel - place additional content here--> 
     <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
      <ListBox ItemsSource="{Binding Path=Options}"> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <StackPanel> 
          <!-- Title --> 
          <TextBlock Text="{Binding Path=Description}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" /> 
          <!-- Selection --> 
          <toolkit:ListPicker ItemsSource="{Binding Path=Options}" 
               SelectedItem="{Binding CurrentSelection, Mode=TwoWay}" > 
           <toolkit:ListPicker.ItemTemplate> 
            <DataTemplate> 
             <TextBlock Text="{Binding Path=Description}" /> 
            </DataTemplate> 
           </toolkit:ListPicker.ItemTemplate> 
           <toolkit:ListPicker.FullModeItemTemplate> 
            <DataTemplate> 
             <TextBlock Text="{Binding Path=Description}" /> 
            </DataTemplate> 
           </toolkit:ListPicker.FullModeItemTemplate> 
          </toolkit:ListPicker> 
         </StackPanel> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
     </Grid> 
    </Grid> 

</phone:PhoneApplicationPage> 

ここでコードが

namespace StackOverflowWP7 
{ 
    using Microsoft.Phone.Controls; 

    public partial class SO9369491 : PhoneApplicationPage 
    { 
     // Constructor 
     public SO9369491() 
     { 
      InitializeComponent(); 

     } 

    } 

} 

namespace StackOverflowWP7.SO9369491_ 
{ 
    using System.Collections.ObjectModel; 
    using System.Linq; 

    public class Menu : Option 
    { 
     public Menu() 
      : base("Main Menu") 
     { 
     } 
    } 

    public class Option 
    { 
     public Option() {} 

     public Option(string Name, params string[] choices) 
     { 
      this.Description = Name; 
      foreach (var choice in choices) 
      { 
       this._options.Add(new Option(choice)); 
      } 
     } 

     public string Description { get; set; } 

     private ObservableCollection<Option> _options = new ObservableCollection<Option>(); 
     public ObservableCollection<Option> Options { get { return _options; } } 

     private Option _CurrentSelection; 

     public Option CurrentSelection 
     { 
      get { 
       return _CurrentSelection; 
      } 
      set 
      { 
       if (_options.Contains(value)) 
       { 
        _CurrentSelection = value; 
       } 
       else 
       { 
        _CurrentSelection = _options.FirstOrDefault((o) => o.Description == value.Description); 
       } 
      } 
     } 

    } 

} 
+0

優秀なの背後に、私が必要とまさに、ありがとうございました!もう一つ(関連する) - SelectedItemバインディングを適用すると、デザイナーは "SelectedItemは常に有効な値に設定する必要があります"というエラーを投げています。これは、デザインd:DataContext(これは名前が重複しているのが好きではないと思われます。http://imagebin.org/199982)このエラーを修正/抑制する方法について助言していますか?完全なエラーメッセージ:http://pastebin.com/XQM0zWJZ – Josh

+0

これらの2つのオプションは別個のインスタンスです。 SelectedIndexを使用してデフォルトを設定する必要があります。それ以外の場合は、IComparableを実装するか、GetHashCode()をオーバーライドしてみてください。 –

+0

うーん、両者を試してみましたが、動かすことができませんでした。実際の実行時の問題はうまくいきますが、サンプルの設計データだけは気にしないでください。ありがとう! – Josh

関連する問題