2010-04-29 2 views
8

ListBox selectedItems를 배열에 바인딩하려고합니다. 그러나 .NET은 런타임에 예외를 throw합니다.ListBox SelectedItems Binding

d.SetBinding(ListBox.SelectedItemsProperty, new Binding { Source = SomeArray }); 

여기서 d은 XAML의 일부 ListBox입니다.

예외 :

선택 항목을 바인딩 할 수 없습니다.

왜?

답변

1

ListBox.SelectedItems은 읽기 전용입니다. 대신 ListBox.SelectedItem에 바인딩하겠습니까?

+0

아니, 난 몇 가지 선택 항목이 내가 그 속성은 읽기 전용으로되어 있기 때문에, 당신은 무엇을 위해 그것을 사용할 수 없습니다 선택한 상태 – Polaris

+1

에 목록 상자에서 그들을 표시 할 필요. 내가 생각할 수있는 유일한 방법은 개별 ListBoxItem.IsSelected 속성을 설정하는 것이다. 바인딩을 고집하는 경우 가장 쉬운 방법은 예를 들어 속성이 변경된 이벤트 핸들러에서 커스텀 로직을 가지고 연결된 SelectedItems'DependencyProperty '. – wpfwannabe

1

정확한 질문이나 정확한 시나리오를 이해할 수 있을지 모르겠지만 - "MyOtherListbox"라는 다른 목록 상자에서 선택한 목록을 하나의 목록 상자에 표시하고 싶다고 가정하면 바인딩을 설정하기 만하면됩니다 모드를 '편도'로 설정하면 오류가 발생합니다.

당신은 당신은리스트 박스의 인 selectionchanged 이벤트를 구독 할 수 있습니다

d.SetBinding(ListBox.ItemsSourceProperty, new Binding { Source = MyOtherListbox.SelectedItems, Mode = BindingMode.OneWay}); 
+0

내가 뭔가를 사용해야합니다 : d.SetBinding (ListBox.SelectedItemsProperty, 새 바인딩 {Source = SomeArray, Mode = OneWay}); 그러나 동일한 예외가 발생합니다. – Polaris

+1

아니요, Get 접근 자만 있기 때문에 SelectedItemsProperty에 바인딩 할 수 없습니다. 다음 스레드를 읽으면 가장 가까운 사용자에게 도달 할 것이라고 생각합니다. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f0183ef3-ee0e-4de9 -86c7-73d2072baba7 –

+0

큰 실. 그것은 내가 예상 한대로 작동합니다. – Polaris

7

그런 짓을하고 핸들러에서 선택한 항목의 컬렉션을 동기화 할 수 있습니다.

이 예제에서 Windows DataContext는 생성자에서 자신 (this)으로 설정되었습니다. 또한 이벤트 핸들러에서 로직 계층 (MVVM을 사용하는 경우 ViewModel)을 쉽게 호출 할 수 있습니다. XAML에서

:

<StackPanel> 

    <ListBox 
     ItemsSource="{Binding ListBoxItems}" 
     SelectionMode="Multiple" 
     SelectionChanged="ListBox_SelectionChanged"> 
    </ListBox> 

    <ItemsControl 
     ItemsSource="{Binding SelectedItems}"> 
    </ItemsControl> 

</StackPanel> 

과의 코드 숨김

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    foreach (string item in e.RemovedItems) 
    { 
     SelectedItems.Remove(item); 
    } 

    foreach (string item in e.AddedItems) 
    { 
     SelectedItems.Add(item); 
    } 
} 
+2

이것은 OneWayToSource 바인딩으로 작동하는 것 같습니다. SelectedItems 컬렉션을 변경하면 변경 내용이 목록 상자에 반영되지 않습니다. –

+1

@ BogdanVerbenets 모드를 TwoWay로 설정하고 UpdateSourceTrigger를 PropertyChanged로 설정하면 트릭이 실행됩니까? 그건 그렇고, 우리도 같은 이름이야! : D –

+2

뷰 모델을 호출하기 위해 코드 숨김에서 이벤트 처리기를 사용하면 MVVM 패턴을 따르지 않기 때문에 Downvoted. 코드 숨김을 신경 쓸 필요가 없다면 (그리고 난 상관 없습니다.) 그러나 코드 숨김에서 뷰 모델을 호출하여 뷰 모델을 오염시키지 마십시오. – aaronburro

3

이 작업 솔루션 ... 선택 SelectedItemsProperty이 바인딩을 새로 고쳐지지 않는 변경 그러나 때,

다음과 같이 맞춤 컨트롤을 만들 수 있습니다.

public class MyListBox: ListBox{ 

    public MyListBox() 
    { 
     this.SelectionChanged += (s,e)=>{ RefreshBindings(); }; 
    } 

    private void RefreshBindings() 
    { 
     BindingExpression be = 
      (BindingExpression) GetBindingExpression(
             SelectedItemsProperty); 
     if(be!=null){ 
       bd.UpdateTarget(); 
     } 
    } 

} 
,210

또는 아래와 같이 모든 목록 상자에서 이벤트를 정의 할 수 있습니다 앱에 ..

myListBox.SelectionChanged += (s,e) => { 
    BindingExpression be = 
     (BindingExpression) myListBox.GetBindingExpression(
             ListBox.SelectedItemsProperty); 
    if(be!=null){ 
     bd.UpdateTarget(); 
    } 
}; 
+0

감사합니다. 내 대답에 해결 방법을 추가했습니다. – dovid

0

내 트릭 : XAML에서 (! 작동) Count 속성 변경에 컨버터를 실행 MultiBinding, 힘을 사용합니다.

<MultiBinding Converter="{StaticResource SelectedRowsTotal }"> 
    <Binding Path="SelectedItems" ElementName="listBox1" /> 
    <Binding Path="SelectedItems.Count" ElementName="listBox1" /> 
</MultiBinding> 

변환기 :

public class SelectedRowsTotal : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     var selecteds = values as IEnumerable; 

     if (selected == null) 
      return null; 

     return selecteds.Cast<SomeType>().Sum(x=> x.SomeProperty) = total; 
    } 

    object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     return null; 
    } 
}