Question

Je suis TRES nouveau sur WPF et j'essaie toujours de comprendre ce qui se passe dans le XAML.

J'aimerais peupler une liste déroulante avec les valeurs d'une collection de chaînes dans my.settings. Je peux le faire dans le code comme ceci:

Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings

... et ça marche.

Comment puis-je faire cela dans mon XAML? est-ce possible?

Merci

Était-ce utile?

La solution

Oui , vous pouvez (et devriez le faire pour la plupart) déclarer des liaisons en XAML, car c'est l'une des fonctionnalités les plus puissantes de WPF.

Dans votre cas, pour associer la zone de liste déroulante à l'un de vos paramètres personnalisés, vous utiliseriez le code XAML suivant:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="clr-namespace:WpfApplication1.Properties"
    Title="Window1">
    <StackPanel>
        <ComboBox
            ItemsSource="{Binding Source={x:Static p:Settings.Default}, Path=MyCollectionOfStrings}" />
    </StackPanel>
</Window>

Notez les aspects suivants:

  • Nous avons déclaré un espace de noms XML avec le préfixe 'p' qui pointe vers l'espace de noms .NET où la classe 'Settings' habite afin de pouvoir s'y référer en XAML
  • Nous avons utilisé l'extension de balisage '{Binding}' afin de déclarer une liaison en XAML
  • Nous avons utilisé l'extension de balisage 'Static' afin d'indiquer que nous souhaitons faire référence à un membre de classe statique ('shared' in VB) en XAML

Autres conseils

J'ai une solution plus simple qui utilise une extension de balisage personnalisée. Dans votre cas, il pourrait être utilisé comme ceci:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:WpfApplication1"
    Title="Window1" Height="90" Width="462" Name="Window1">
    <Grid>
        <ComboBox ItemsSource="{my:SettingBinding MyCollectionOfStrings}" />
    </Grid>
</Window>

Vous pouvez trouver le code C # de cette extension de balisage sur mon blog ici: http: / /www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/

C'est possible. En C #, je le fais comme ça (pour un simple bool):

IsExpanded="{Binding Source={StaticResource Settings}, Mode=TwoWay, Path=Default.ASettingValue}"

Je définis la ressource statique " Paramètres " dans Application.Resources de mon App.xaml, ainsi:

<!-- other namespaces removed for clarity -->
<Application xmlns:settings="clr-namespace:DefaultNamespace.Properties" >
 <Application.Resources>
  <ResourceDictionary>
   <settings:Settings x:Key="Settings" />
   <!--stuff removed-->
  </ResourceDictionary>
 </Application.Resources>
</Application>

Votre chemin peut être différent; en C #, vous accédez aux paramètres de l'application dans votre application via

DefaultNamespace.Properties.Settings.Default.ASettingValue

Compris!

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="clr-namespace:WpfApplication1"
    Title="Window1" Height="90" Width="462" Name="Window1">
    <Grid>
        <ComboBox ItemsSource="{Binding Source={x:Static p:Settings.Default}, Path=MyCollectionOfStrings}" />
    </Grid>
</Window>

Merci à tous de m'avoir aidé à atteindre un excellent résultat "Aha!". moment :-) ... après avoir passé un peu plus de temps dans WPF, je comprendrai pourquoi cela fonctionne.

Vous pouvez également stocker la liste sous forme de chaîne délimitée dans les paramètres, puis utiliser un convertisseur.

<ComboBox ItemsSource="{Binding Default.ImportHistory,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,Converter={StaticResource StringToListConverter},ConverterParameter=|}" IsEditable="True">
/// <summary>
/// Converts a delimited set of strings to a list and back again. The parameter defines the delimiter
/// </summary>
public class StringToListConverter : IValueConverter {
 /// <summary>
 /// Takes a string, returns a list seperated by {parameter}
 /// </summary>
 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
     string serializedList = (value ?? string.Empty).ToString(),
            splitter = (parameter ?? string.Empty).ToString();
     if(serializedList.Trim().Length == 0) {
         return value;
     }
     return serializedList.Split(new[] { splitter }, StringSplitOptions.RemoveEmptyEntries);
 }
 /// <summary>
 /// Takes a list, returns a string seperated by {parameter}
 /// </summary>
 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
     var items = value as IEnumerable;
     var splitter = (parameter ?? string.Empty).ToString();
     if(value == null || items == null) {
         return value;
     }
     StringBuilder buffer = new StringBuilder();
     foreach(var itm in items) {
         buffer.Append(itm.ToString()).Append(splitter);
     }
     return buffer.ToString(0, splitter.Length > 0 ? buffer.Length - splitter.Length : buffer.Length);
 }
}

Ensuite, quand un bouton de navigation est cliqué, vous pouvez ajouter à la liste:

var items = Settings.Default.ImportHistory.Split('|');
if(!items.Contains(dlgOpen.FileNames[0])) {
 Settings.Default.ImportHistory += ("|" + dlgOpen.FileNames[0]);
}
cboFilename.SelectedValue = dlgOpen.FileNames[0];
Settings.Default.Save();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top