2010-04-29 24 views
8

Listbox selectedItems öğesini diziye bağlamak istiyorum. Ancak, .NET çalışma zamanında istisna atar. dListBox SelectedItems Binding

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

XAML bazı ListBox.

İstisna:

Seçilmiş Öğe bağlı edilemez.

Neden?

cevap

1

ListBox.SelectedItems salt okunurdur. Bunun yerine ListBox.SelectedItem'a bağlamak mı istediniz?

+0

Hayır ben birkaç seçili öğeleri var ve bu özellik salt okunur olduğundan, sizin için ne kullanamazsınız seçilmiş durumda – Polaris

+1

yılında ListBox onlara göstermek istiyorum istemek. Düşünebildiğim tek şey, "ListBoxItem.IsSelected" özelliklerini ayarlamaktır. Bağlama konusunda ısrar ederseniz, en kolay yol sizin için oluşturmanızdır. Özel bir SelectedItems 'DependencyProperty' özelliği, özellik değiştirici olay işleyicisiyle değiştirildi. – wpfwannabe

1

Sorunuzu doğru olarak veya tam senaryoyu anlayabildiğimden emin değilim - ama bir liste kutusu "d" olmasını istediğinizi varsayarak, başka bir liste kutusunda "MyOtherListbox" ı seçmiş olduğunuz öğeleri göstermeniz yeterlidir. modu 'tek yönlü' başka bir hata getirecektir.

Sen ListBoxBindingContextChanged SelectionChanged olayı abone olabilirsiniz

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

Böyle bir şey kullanmalıyım: d.SetBinding (ListBox.SelectedItemsProperty, yeni Bağlama {Source = SomeArray, Mode = OneWay}); Ancak aynı istisnayı yükseltiyor. – Polaris

+1

Hayır, yalnızca bir erişime sahip olduğundan SelectedItemsProperty'ye bağlanamazsınız. Şu konuya ulaşacağınız en yakın şey, şu ipucunu okursanız ... http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f0183ef3-ee0e-4de9 -86c7-73d2072baba7 –

+0

Harika bir iş parçacığı. Beklediğim gibi çalışıyor. – Polaris

7

böyle bir şey yapmak ve işleyicisi seçili öğeleri koleksiyonunu senkronize olabilir.

Bu örnekte, Windows DataContext kendi başına (bu) yapıcısına ayarlandı. Ayrıca olay işleyicisinden mantıksal bir katmana (MVVM kullanıyorsanız ViewModel) kolayca çağrı yapabilirsiniz. Xaml olarak

:

<StackPanel> 

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

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

</StackPanel> 

Ve arka planda kodlama:

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

Bu OneWayToSource bağlayıcısı olarak çalışıyor gibi görünüyor. SelectedItems koleksiyonunu değiştirirseniz, değişiklikler liste kutusuna yansıtılmaz. –

+1

@BogdanVerbenets Belki Mode TwoWay ve PropertyChanged için UpdateSourceTrigger ayarı hile yapacak? Bu arada, aynı ilk isme sahibiz! : D –

+2

Bir modele çağırmak için arka planda bir olay işleyicisinin kullanılmasının önerilmesi MVVM modelini takip etmediği için reddedildi. Eğer kod arkasında sakıncası yoksa (ve buna rağmen, ama her neyse), bunu kullanın. Ancak lütfen, görünüm modellerini kod arkasından arayarak kirletmeyin. – aaronburro

3

Bu çalışma çözümü ... seçim SelectedItemsProperty bağlamaları yenilemez değiştirir ancak ne zaman olduğunu

aşağıdaki gibi özel bir denetim oluşturabilirsiniz

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

veya aşağıda gösterildiği gibi her listbox olayı tanımlayabilirsiniz uygulamanızda ..

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

teşekkürler. cevabımda bir geçici çözüm ekledim – dovid

0

benim sırrım: xaml, (! O iş) Count mülkiyet değişikliği dönüştürücü yürütmek MultiBinding, güç kullanmak.

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

Dönüştürücü:

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; 
    } 
}