Je veux lier la liste de liste sélectionnée sur la liste. Mais .NET jette une exception à l'exécution.
d.SetBinding(ListBox.SelectedItemsProperty, new Binding { Source = SomeArray });
6 Réponses :
listbox.SelectedItems code> est en lecture seule. Voulez-vous vouloir vous lier à
listbox.selectedItem code> à la place? P>
Non, j'ai plusieurs éléments sélectionnés et je veux les montrer dans la liste de liste dans l'état sélectionné
Puisque cette propriété est en lecture seule, vous ne pouvez pas l'utiliser pour ce que vous voulez. La seule chose à laquelle je passe est de définir des propriétés individuelles listboxItem.isselected code>. Si vous insistez pour la liaison, le chemin le plus facile serait pour vous de créer par exemple. Un
DépendencyProperty code> avec la logique personnalisée dans le gestionnaire d'événements modifié de la propriété.
Je ne suis pas sûr que je comprends votre question correctement ou le scénario exact - mais en supposant que vous vouliez avoir une liste de liste "D" afficher les éléments sélectionnés dans une autre liste "MyotherListbox", alors vous devez simplement définir le mode de liaison. À une seule façon, cela fera une erreur.
Vous pouvez faire quelque chose comme p>
Je dois utiliser quelque chose comme ceci: d.SetBinding (Listbox.SelectedSProperty, nouvelle liaison {Source = SOMARRAY, mode = ecoute}); Mais il augmente la même exception.
Non, vous ne pouvez pas vous attaquer au SELECTEMSPROPERTY, car il n'a qu'un accessor. Je pense que le plus proche que vous obtiendrez, c'est si vous lisez le thread suivant ... social.msdn.microsoft.com/forums/en-us/wpf/thread/...
Cela ne vous rafraîchira pas si les éléments sélectionnés sont modifiés, car SELECTITEMS est la liste et non une collecte ou une liste de liaison observable.
Merci Polaris - Cela signifie-t-il que le thread a répondu à votre question?
Vous pouvez vous abonner à l'événement sélectionné de la liste de liste et dans le gestionnaire synchronisez une collection d'éléments sélectionnés.
Dans cet exemple, Windows DataContext a été défini sur lui-même (ceci) dans son constructeur. Vous pouvez également appeler facilement dans une couche logique (ViewModel si vous utilisez MVVM) à partir du gestionnaire d'événements. P>
in xaml: p> et dans Le code-derrière: p>
Cela semble fonctionner comme une liaison de style detoSource. Si je modifie la collection SELECTECITEMS, les modifications ne sont pas reflétées dans la liste de liste.
@Bogdanverbenets peut-être en mode de réglage sur Twoway et les mises à jourTourcetrigger à la propriétéChanged feront le tour? Au fait, nous avons le même prénom! :RÉ
Townvoted parce que suggérant l'utilisation d'un gestionnaire d'événements dans le code-code pour appeler dans un modèle de vue ne suit pas le motif MVVM. Si cela ne vous dérange pas du code-derrière (et que je pense que tout), utilisez ceci. Mais s'il vous plaît, ne polluez pas la vue des modèles en les appelant à partir de code-indemnité.
Ceci est la solution de travail, mais lorsque la sélection change SELECTELITEMSPROPERTY ne receverez pas les liaisons ...
Vous pouvez créer un contrôle personnalisé comme suit P>
myListBox.SelectionChanged += (s,e) => { BindingExpression be = (BindingExpression) myListBox.GetBindingExpression( ListBox.SelectedItemsProperty); if(be!=null){ bd.UpdateTarget(); } };
Mon astuce: dans xaml, utilisez multibindage code>, convertisseur Force Execute dans
Nombre code> Changement de propriété (Ça marche!).
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;
}
}
Voici une solution de travail, vous pouvez facilement m'adapter à vos besoins:
in P> Dans Code: P> xaml code>: p>
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
namespace ListBoxSelectedItems
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
public class ViewModel : MyNotifyPropertyChanged
{
public ViewModel()
{
ProductListSource.Add(new Product() { Item = "Item_1", IsSelected = false });
ProductListSource.Add(new Product() { Item = "Item_2", IsSelected = false });
ProductListSource.Add(new Product() { Item = "Item_3", IsSelected = false });
}
private ObservableCollection<Product> _productList = new ObservableCollection<Product>();
public ObservableCollection<Product> ProductListSource
{
get => _productList;
set
{
_productList = value;
RaisePropertyChanged(nameof(ProductListSource));
}
}
private readonly Product _selectedProduct;
public Product SelectedProduct
{
get => _selectedProduct;
set
{
var selectedItems = ProductListSource.Where(x => x.IsSelected).ToList();
this.RaisePropertyChanged(nameof(SelectedProduct));
string s = "{";
int n = selectedItems.Count;
for (int i=0; i< n; i++)
{
s += selectedItems[i].ToString();
if (i < n - 1) s += ", ";
}
s += "}";
Debug.WriteLine(s + ".Count= " + n);
}
}
}
public class Product : MyNotifyPropertyChanged
{
private string _item;
public string Item
{
get => _item;
set
{
_item = value;
RaisePropertyChanged(nameof(Item));
}
}
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
_isSelected = value;
RaisePropertyChanged(nameof(IsSelected));
}
}
public new string ToString() => _item;
}
public class MyNotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}