2009-03-18 3 views
1

Quelle est la manière la plus minimale d'échanger dynamiquement UIElement à un certain «slot» sur l'interface utilisateur? J'ai un nombre de UIElement s et basé sur une liaison de données externe (par exemple une sélection de liste déroulante) je veux que l'un d'eux soit affiché et celui qui était actuellement visible pour être caché. Donc, le comportement est un peu comme le TabControl mais sans l'onglet, le chrome et les instances de tabitem. Donc, je pourrais réellement utiliser le TabControl et remplacer le modèle de contrôle. Mais est-ce vraiment l'approche la plus minimale?contrôle pour échanger UIElements dans WPF

Répondre

1

Vous avez plusieurs options. Comme Bryan l'a mentionné, Data Template Selectors peut certainement fonctionner, bien que j'ai décidé qu'ils sont souvent exagérés. Prenez votre exemple par exemple - si vous voulez lier la visibilité d'un élément à la sélection dans un ComboBox, je préférerais un ValueConverter à la place. Passez le ComboBox.SelectedItem au Converter et avoir le retour d'une valeur de visibilité:

public class MyObjectToVisibleOrCollapsed : IValueConverter 
{ 
    #region IValueConverter Members 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value is MyObject) 
     { 
      var myObject = (MyObject)value; 
      if (myObject.SomeState) 
      { 
       return Visibility.Visible; 
      } 
     } 

     return Visibility.Collapsed; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

Maintenant dans votre Window.Resources, créez une instance de la ValueConverter et se lient l'élément à l'aide de l'instance ComboBox.SelectedItemValueConverter:

<local:MyObjectToVisibleOrCollapsed x:Key="myObjectToVisibleOrCollapsed"/> 
<DataTemplate x:Key="MyTemplate"> 
    <TextBlock Text="{Binding Path=myText}" 
       x:Name="MyText" 
       Visibility="{Binding ElementName=MyComboBox, Path=SelectedItem, Converter={StaticResource myObjectToVisibleOrCollapsed}, Mode=Default}" /> 
</DataTemplate> 

Et bien sûr, vous pouvez réutiliser le ValueConverter pour tous les éléments de votre DataTemplate (et s'il y en a beaucoup, alors l'approche du sélecteur de modèle de données devient plus souhaitable).

[Avertissement: le code ci-dessus a été haché hors de la mémoire et non testé - il peut avoir besoin d'un peu de peaufinage]

2
<ContentControl Content="{Binding SomePropertyThatYieldsTheContent}"/> 
+0

Basé sur la réponse à http://stackoverflow.com/questions/1287995 Je pense qu'un ContentPresenter serait un meilleur choix ici. – Wilka

-1

La façon dont je le fais est à la couche les éléments les uns sur les autres et changer leur propriété programatically de visibilité du visible à Collapsed et à nouveau au besoin.

+0

Nos concepteurs ne sont pas bons à C# mais ils sont ceux qui définissent l'interface utilisateur. – bitbonk

1

Je ne sais pas si cela est la manière la plus succincte, mais si vous utilisez un DataTemplate, vous pouvez utiliser DataTrigger s (l'hypothèse est que la visibilité initiale est Collapsed):

<DataTemplate.Triggers> 
    <DataTrigger Binding="{Binding Path=SourceProperty.ValueType}"> 
     <DataTrigger.Value> 
      <pm:ValueType>Text</pm:ValueType> 
     </DataTrigger.Value> 
     <Setter TargetName="TextEditor" Property="Visibility" Value="Visible" /> 
    </DataTrigger> 
    <DataTrigger Binding="{Binding Path=SourceProperty.ValueType}"> 
     <DataTrigger.Value> 
      <pm:ValueType>Logical</pm:ValueType> 
     </DataTrigger.Value> 
     <Setter TargetName="LogicalEditor" Property="Visibility" Value="Visible" /> 
    </DataTrigger> 
    <DataTrigger Binding="{Binding Path=SourceProperty.ValueType}"> 
     <DataTrigger.Value> 
      <pm:ValueType>DateTime</pm:ValueType> 
     </DataTrigger.Value> 
     <Setter TargetName="DateEditor" Property="Visibility" Value="Visible" /> 
    </DataTrigger> 
... 
+0

Cette méthode fonctionne très bien si vous avez seulement quelques "modes", par ex. un mode "édition" et un mode "lecture seule". J'aime définir Visibilité sur Visible ou Caché et avoir plusieurs éléments dans la même cellule de grille afin que les autres éléments de l'interface utilisateur ne bougent pas pendant votre changement de mode. –

0

Regardez dans Data Template Selectors, Bea Stollnitz a un bon poste here. Fondamentalement, vous utiliserez un ContentPresenter dans chacune de vos "tranches" d'interface utilisateur, puis utilisez la propriété ContentTemplateSelector pour définir le sélecteur de modèle que vous utiliserez.

0

Je crée des contrôles utilisateur personnalisés pour chaque possible « vue ».

Leur visibilité est modifiée en utilisant C#, tu. Peu de codage nécessaire.

La principale raison de cette approche est la facilité de développement - le concepteur se concentre sur une vue particulière plutôt que sur l'ensemble de tous les contrôles possibles qui seront là.