2016-09-16 2 views
0

질문 목록을 제공하기 위해 Windows 10 앱을 만들려고합니다. 각 질문은 질문 텍스트 (TextBlock) 및 가능한 대답 목록 (ToggleButton으로 구성된 DataTemplate을 가리키는 ListView)을 표시합니다.ListView 내의 UWP ListView가 INotifyPropertyChanged를 준수하지 않습니다.

프로그램이 시작되고 각 Answer/PossibleAnswer가 표시됩니다. 이제 각각의 질문을 단일 답변으로 제한하려고합니다. 즉, 하나의 PossibleAnswer (ToggleButton)이 선택되면 해당 질문에 대한 다른 항목은 선택 취소해야합니다. 문제는 PossibleAnswer 클래스에서 INotifyPropertyChanged를 구현하고 적절한 메서드를 호출 했음에도 불구하고 발생하지 않습니다. 나는 심지어 도움이 될 것이라는 희망으로 Answer 클래스에 이것을 구현했지만, 그렇지 않았다.

나는 분명히 벙어리 일을하고 있습니까? 어떤 도움이라도 대단히 감사하겠습니다.

참고 : 하나의 질문에서 RadioButton을 확인하면 다른 모든 질문에서 RadioButtons가 선택 취소되므로 ToggleButtons를 사용하고 있습니다.

내 XAML 파일 ([각 질문]리스트 뷰 TextBlock의 (질문 텍스트)와 ListView에 구성된 DataTemplate을 가리키는 [PossibleAnswers])

<Page x:Class="QuestionsnAnswers.MainPage" ... > 
    <Page.Resources> 
     <DataTemplate x:Key="myAnswersTemplate" x:DataType="local:Answer"> 
      <RelativePanel> 
       <TextBlock Text="{Binding QuestionText}"/> 
       <ListView Margin="0, 20 ,0 ,0" 
          ItemsSource="{Binding PossibleAnswers}" 
          ItemTemplate="{StaticResource myPossibleAnswersTemplate}"> 
       </ListView> 
      </RelativePanel> 
     </DataTemplate> 

     <DataTemplate x:Key="myPossibleAnswersTemplate" x:DataType="local:PossibleAnswer"> 
      <ToggleButton Content="{Binding PossibleAnswerText}" IsChecked="{Binding IsChecked}" Click="PossibleAnswerClicked" /> 
     </DataTemplate> 
    </Page.Resources> 

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <ListView Name="uiQuestionsnAnswers" ItemTemplate="{StaticResource myAnswersTemplate}"/> 
    </Grid> 
</Page> 

내 MainPage 파일 : (A 한 페이지 이 문제를 해결하려면 PossibleAnswers의 목록)

public sealed partial class MainPage : Page 
{ 
    ObservableCollection<Answer> Answers = new ObservableCollection<Answer>(); 

    public MainPage() 
    { 
     this.InitializeComponent(); 

     //populate example answers 
     Answers.Add(new Answer { AnswerId = 1, QuestionText = "Question 1" }); 
     Answers.Add(new Answer { AnswerId = 2, QuestionText = "Question 2" }); 
     Answers.Add(new Answer { AnswerId = 3, QuestionText = "Question 3" }); 
     uiQuestionsnAnswers.ItemsSource = Answers; 
    } 

    private void PossibleAnswerClicked(object sender, RoutedEventArgs e) { 
     //get the reference to this togglebutton's PossibleAnswer and update the model. 
     ListViewItemPresenter parent = VisualTreeHelper.GetParent(sender as DependencyObject) as ListViewItemPresenter; 
     PossibleAnswer possAnswer = parent.Content as PossibleAnswer; 
     possAnswer.IsChecked = true; 
    } 
} 


class Answer : INotifyPropertyChanged { 
    public int AnswerId { get; set; } 
    public string QuestionText { get; set; } 
    public ICollection<PossibleAnswer> PossibleAnswers { get; set; } 
    public int ChosenPossibleAnswerId { get; set; } 

    public Answer() { 
     PossibleAnswers = new List<PossibleAnswer>(); 
     PossibleAnswers.Add(new PossibleAnswer { ThisAnswer = this, PossibleAnswerId = 1, PossibleAnswerText = "yes" }); 
     PossibleAnswers.Add(new PossibleAnswer { ThisAnswer = this, PossibleAnswerId = 2, PossibleAnswerText = "no" }); 
     PossibleAnswers.Add(new PossibleAnswer { ThisAnswer = this, PossibleAnswerId = 3, PossibleAnswerText = "I don't know" }); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged(String propertyName = "") { 
     if (PropertyChanged != null) { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    internal void setChosenAnswer(int possibleAnswerId) { 
     //record this possibleAnswer as the answer to this question. 
     ChosenPossibleAnswerId = possibleAnswerId; 

     foreach (PossibleAnswer possAnswer in PossibleAnswers) { 
      if (possAnswer.PossibleAnswerId != ChosenPossibleAnswerId) { 
       possAnswer.IsChecked = false; 
       Debug.WriteLine("Answer " + AnswerId + " has unchecked possible answer " + possAnswer.PossibleAnswerId); 
      } 
     } 
     NotifyPropertyChanged(); 
    } 
} 


class PossibleAnswer : INotifyPropertyChanged { 
    public Answer ThisAnswer { get; set; } 
    public int PossibleAnswerId { get; set; } 
    public string PossibleAnswerText { get; set; } 

    private bool _IsChecked = false; 
    public bool IsChecked { 
     get { 
      return _IsChecked; 
     } 
     set { 
      _IsChecked = value; 
      if (value == true) { 
       ThisAnswer.setChosenAnswer(PossibleAnswerId); 
      } 
      else { 
       NotifyPropertyChanged("IsChecked"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged(String propertyName = "") { 
     if (PropertyChanged != null) { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

답변

1

각을 답변의 목록을 보여주기 위해, 우리는 다음과 같이 TwoWayIsCheckedBinding Mode을 설정할 수 있습니다

,
<ToggleButton Click="PossibleAnswerClicked" Content="{Binding PossibleAnswerText}" IsChecked="{Binding IsChecked, Mode=TwoWay}" /> 

{Binding} markup extension의 경우 대부분의 경우 기본 모드는 단방향입니다. 읽기 전용 데이터에서도 잘 작동합니다. 사용자가 UI에서 값을 변경 한 내용이 자동으로 데이터 소스로 푸시되고 싶다면 양방향 바인딩을 사용해야하며 읽기 - 쓰기 데이터에 적합합니다. 여기서 단방향 바인딩을 사용하면 사용자가 ToggleButton을 클릭하면 바인딩이 적용되지 않으므로 코드가 작동하지 않습니다.

+0

완벽하게 작동했습니다. 고맙습니다. – user328414

관련 문제