2012-02-20 1 views
0

Options (Menu.Options)이 포함 된 Menu 개체 (DataContext로 설정 됨)가 있는데,이 개체에는 Name (Option.Name)과 많은 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가 런타임에 생성되므로 메서드에 제공된 매개 변수 만 사용하여이 작업을 수행해야합니다. 따라서 실제 컨트롤 이름을 지정할 수는 없습니다 (필자가 알고있는 한).

나는 두 가지 옵션을 볼 수 있습니다

1)는 CurrentSelection 내가 그 ListPicker

2 마지막으로 선택한 항목에 대한 참조를 넣을 수 있습니다 Menu.Option, 내부를하려면)를 Selected을하기를 속성은 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

두 옵션은 별도의 인스턴스입니다. SelectedIndex를 사용하여 기본값을 설정해야합니다. 그렇지 않으면 IComparable을 구현하거나 GetHashCode()를 재정의하십시오. –

+0

흠, 그 두 가지를 모두 시험해 보았지만 제대로 작동시키지 못했습니다. 실제 실행 시간면이 잘 작동하기 때문에 예제 디자인 데이터 만 신경 쓸 필요가 없습니다. 감사! – Josh