2017-02-18 10 views
0

단추를 눌렀을 때 선택란을 선택했는지에 따라 목록 상자에 표시 할 간단한 문자열 목록이 있습니다. 내 버튼 리스너에이 논리를 가지고 :목록 상자의 항목이 잘못 업데이트 됨 WPF

private void fileSavePerms_Click(object sender, RoutedEventArgs e) 
{ 
    foreach (CheckBox checkbox in checkboxList) 
    { 
     if (checkbox.IsChecked == true && !permissionList.Contains(checkbox.Name)) 
     { 
      permissionList.Add(checkbox.Name); 
     } 

     else if (checkbox.IsChecked == false && permissionList.Contains(checkbox.Name)) 
     { 
      permissionList.Remove(checkbox.Name); 
     } 
    } 
    permListBox.ItemsSource = permissionList; 
} 

는 지금까지 내가 아는 한, 이것은 당신이 버튼 클릭에 대한 매우 간단한 데이터 바인딩을 할 수있는 방법이다. 그러나 의도적으로 처음으로 목록 상자가 업데이트되지만 상자를 채우려는 목록의 잘못된 내용으로 업데이트됩니다. 나는 출력과 식별 할 수있는 패턴을 볼 수 없다.

게다가 잠시 (몇 번의 버튼 클릭) 후에 "an ItemsControl is inconsistent with its items source"이라는 예외가 발생합니다.

내 바인딩을 잘못 설정했거나 올바르지 않은 시간에 ItemsControl을 할당하고 있습니까?

는 업데이트 : 목록 상자

XAML : 모든

<ListBox x:Name="permListBox" ItemsSource="{Binding permissionList}" HorizontalAlignment="Left" Height="36" Margin="28,512,0,0" VerticalAlignment="Top" Width="442"/>

+0

이 목록 상자에 해당하는 XAML도 공유 할 수 있습니까? –

+0

@DaveS 목록 상자에 대한 XAML을 추가했습니다. 감사합니다. – James

답변

2

먼저 컨트롤에만 속성을 바인딩 할 수 있습니다. 필드를 바인딩 할 수 없습니다. 따라서 permissionListWindow.DataContext 속성으로 설정 한 DataContext 개체의 속성이어야합니다.

이 값이 올바르게 설정되면 매번 List<string>을 새로 만든 다음 컨트롤에 바인딩 된 속성에 할당 할 수 있습니다. 컨트롤의 ItemsSource 속성에 할당하지 않아도됩니다.

창 데이터 컨텍스트가 창 자체로 설정되어 있다고 가정 해 봅시다. XAML에서

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     this.DataContext = this; 
    } 

    public List<string> PermissionList 
    { 
     get { return (List<string>)GetValue(PermissionListProperty); } 
     set { SetValue(PermissionListProperty, value); } 
    } 

    public static readonly DependencyProperty PermissionListProperty = 
     DependencyProperty.Register(
      "PermissionList", 
      typeof(List<string>), 
      typeof(MainWindow), 
      new PropertyMetadata(new List<string>()) 
     ); 

    private void fileSavePerms_Click(object sender, RoutedEventArgs e) 
    { 
     // You create a new instance of List<string> 
     var newPermissionList = new List<string>(); 

     // your foreach statement that fills this newPermissionList 
     // ... 

     // At the end you simply replace the property value with this new list 
     PermissionList = newPermissionList; 
    } 
} 

은 당신이해야합니다 파일 : 물론

<ListBox 
    ItemsSource="{Binding PermissionList}" 
    HorizontalAlignment="Left" 
    VerticalAlignment="Top" 
    Margin="28,512,0,0" 
    Height="36" 
    Width="442"/> 

이 솔루션을 향상시킬 수있다. 더 이상 List<string>의 때마다 새 인스턴스를 만들 필요가 없습니다하지만 당신은 목록을 삭제하고 foreach 문에 새 항목을 추가 할 수 있도록

  • 당신은 System.Collections.ObjectModel.ObservableCollection<string> 유형을 사용할 수 있습니다.
  • 이 사용 권한 목록이있는 ViewModel 클래스 (예 : MainViewModel)를 사용하고 INotifyPropertyChanged 인터페이스도 구현 한 다음이 클래스의 인스턴스를 WPF 창의 DataContext 속성으로 설정할 수 있습니다.
+0

DependencyPropertys를 조사해도 매우 유용합니다. 유용한 도구 인 것 같습니다. 또한 위의 솔루션에 대해 언급 할 가치가있는 XAML 바인딩은 {Binding PermissionList} – James

+0

으로 설정해야합니다. 그래도 많은 감사합니다. – James