J'écris un Dans le contexte de ma demande, je sais ce que le type réel du Je cherche donc un moyen de supprimer un élément d'une source de données, sans connaître son type. Je pourrais utiliser la réflexion, mais cela se sale ... Jusqu'à présent, la meilleure solution que j'ai proposée consiste à utiliser mais je ' Je ne suis pas vraiment heureux avec ça, je suis sûr qu'il doit y avoir une meilleure façon. Toutes les suggestions seraient appréciées! P> p> itemsControl code> (un conteneur de document à onglets), dans lequel chaque élément (onglet) peut se retirer de l'interface utilisateur lorsque l'utilisateur la ferme. Cependant, je ne peux pas l'enlever directement à partir de la collection
itemsControl.items code>, car les éléments peuvent être en tableau. Donc, je dois le supprimer du
itemsSource code>, qui peut être n'importe quoi (
icollection code>,
datatable code>,
datasourceprovider code> .. .).
itemsSource code> sera, mais je veux que le contrôle soit plus générique afin que je puisse le réutiliser plus tard. < / p>
dynamique code>: p>
4 Réponses :
La conception pratique dicte que vous devriez vraiment savoir ce que votre Toutefois, si vous êtes absolument intention d'une sorte de fonctionnalité générique pour le retrait, de jeter votre itemSource code> est et pouvoir le supprimer directement. La liaison met ensuite à jour automatiquement la vue du cours. P>
itemsSource code> à
icollection code> ou
icollection
supprimer code> sonne comme un moyen de parcourir mieux / plus fiable que d'utiliser les fonctionnalités dynamiques de .NET. P>
En fait, une bonne conception garantirait que le itemsControl code> n'a aucune connaissance des types dans les éléments
itemsSource code> du tout.
Je serais d'accord si j'avais le contrôle total sur cette propriété ArticleSource ... mais je ne le fais pas. Cela fait partie du WPF, est de type objet code>, et peut être tout ce qui supporte l'énumération. Et mon contrôle est conçu pour accepter quoi que ce soit, je ne veux pas me limiter à un type spécifique
@Thomas: Quel est le problème avec la solution de mon 2e paragraphe BTW?
Rien n'est faux, je ne suis pas celui qui vous a voté ... à propos de votre 2e paragraphe, malheureusement, je ne peux pas faire cela, car je ne connais pas le type d'élément réel et Icollection
icollection code>
Comme vous l'avez trouvé, votre L'astuce consiste à assurer que chaque élément est enveloppé par une classe personnalisée (conteneur d'élément) de votre choix. Votre De là, vous pouvez définir des propriétés sur votre conteneur d'élément personnalisé que vous liez dans votre modèle par défaut. Par exemple, vous pouvez avoir une propriété appelée Vous ne changerez pas du tout la source de données sous-jacente. Au lieu de cela, vous modifierez une couche spécifique au contrôle sur les éléments de données sous-jacents qui vous donnent les informations dont vous avez besoin pour implémenter votre contrôle. P> itemsControl code> n'a pas de connaissance intrinsèque des éléments liés - ces types sont fournis par les consommateurs de votre contrôle. Et vous ne pouvez pas modifier directement la collection car elle peut être liée aux données. P>
itemsControl code> Vous pouvez fournir ceci dans la méthode
getcontainerforitemverride code>. P>
état code> qui change entre
docked code>,
flottant code> et
fermé code>. Votre modèle utiliserait cette propriété pour déterminer comment - et si - pour montrer l'article. P>
Kent, merci pour votre réponse. J'ai déjà créé un conteneur personnalisé et une nervure à la nervure GetContainerForItemoverride. Mais le fait est que je veux vraiment supprimer l'article de la collection sous-jacente, je ne veux pas simplement le cacher. Peut-être que je devrais simplement déléguer la mise en œuvre de «proches» à l'utilisateur, en manipulant un événement (code-derrière) ou à la liaison d'une commande (ViewModel)
@Thomas: pas de problème. Pouvez-vous expliquer pourquoi il est dont vous avez besoin de supprimer l'article? Peut-être qu'une vue de collection filtrée suffirait? Ou peut-être que votre article doit exécuter une commande lorsque l'utilisateur la ferme et que le retrait est à la hauteur du code consommateur. Il me semble que votre désir de créer un contrôle générique ne peut pas fonctionner si vous vous enlève.
Le contrôle affiche une liste de documents ouverts (feuilles de calcul SQL dans cette affaire). Il est lié à une liste de feuilles de calcul exposées par une vue de vue. Lorsque je clique sur le bouton Fermer sur un onglet (partie du modèle du TabdocumentContainerItem), le conteneur appelle le closab sur son parent (TabdocumentContainer), qui supprime le document de la collection de la feuille de calcul. En fait j'ai trouvé une solution, je vais le poster dans quelques minutes
the Ceci ne fonctionnera que si la vue de la collection liée à itemCollection code> renvoyé par
itemsControl.items code> ne vous permettra pas d'appeler supprimer directement, mais il implémente
ieditablecollectionvoirview code>
et vous permet d'appeler la méthode Supprimer dans cette interface. itemSource code> implémente
ieditablecollectionvoir code> lui-même. La vue de la collection par défaut sera pour la plupart des collections mutables, bien que non pour les objets qui implémentent
ICollection code> mais pas
ilist code>. p>
Réponse intéressante, je ne savais pas à propos de cette interface. Cependant, je pense que je vais coller à la solution que j'ai trouvée (voir ma réponse), car il est plus adéquat dans mon cas. De plus, si l'itemSource est un iéalable, CanRemove retournera FALSE, mais la viewModel pourrait avoir accès à la collection effective et être capable de supprimer l'article.
Solution géniale frère. Vous venez de résoudre un mauvais bogue pour moi: AvalONDock.CodePlex.com/workItem/13168
OK, j'ai trouvé une solution ...
Si le Si ce n'est pas de la banquette, je soumette un événement pour inviter l'utilisateur à confirmer et je supprimai le conteneur directement à partir d'éléments itemsSource code> est la banquette, je soumettez un événement (à utiliser avec code-derrière) ou appelez une commande (à utiliser avec une vue de vue) pour supprimer l'élément de la itemSource code> collection. P> li>
code> p> p>
public static readonly DependencyProperty CloseTabCommandProperty =
DependencyProperty.Register(
"CloseTabCommand",
typeof(ICommand),
typeof(TabDocumentContainer),
new UIPropertyMetadata(null));
public ICommand CloseTabCommand
{
get { return (ICommand)GetValue(CloseTabCommandProperty); }
set { SetValue(CloseTabCommandProperty, value); }
}
public event EventHandler<RequestCloseTabEventArgs> RequestCloseTab;
public event EventHandler<TabClosingEventArgs> TabClosing;
internal void CloseTab(TabDocumentContainerItem tabDocumentContainerItem)
{
if (ItemsSource != null) // Databound
{
object item = ItemContainerGenerator.ItemFromContainer(tabDocumentContainerItem);
if (item == null || item == DependencyProperty.UnsetValue)
{
return;
}
if (RequestCloseTab != null)
{
var args = new RequestCloseTabEventArgs(item);
RequestCloseTab(this, args);
}
else if (CloseTabCommand != null)
{
if (CloseTabCommand.CanExecute(item))
{
CloseTabCommand.Execute(item);
}
}
}
else // Not databound
{
if (TabClosing != null)
{
var args = new TabClosingEventArgs(tabDocumentContainerItem);
TabClosing(this, args);
if (args.Cancel)
return;
}
Items.Remove(tabDocumentContainerItem);
}
}