2008-10-15 5 views
8

Je suis TRÈS nouveau sur WPF, et j'essaie toujours de comprendre ce qui se passe dans XAML.WPF Lier la collection My.Settings aux objets Combobox

Je voudrais remplir une zone de 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 il fonctionne.

Comment est-ce que je peux faire ceci dans mon XAML? c'est possible?

Merci

Répondre

18

Oui, vous pouvez (et devrait, pour la plupart) déclarer les liaisons en XAML, puisque c'est l'une des caractéristiques les plus puissantes de WPF.

Dans votre cas, pour lier le ComboBox à un de vos paramètres personnalisés vous utilisez 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> 

avis sur les aspects suivants:

  • Nous avons déclaré un espace de noms XML avec le préfixe 'p' qui pointe vers l'espace de nommage .NET où la classe 'Settings' réside pour s'y référer dans XAML
  • Nous avons utilisé l'extension de balisage '{Binding}' pour déclarer une liaison dans XAML
  • Nous avons utilisé l'extension de balisage « statique » afin d'indiquer que nous voulons faire référence à une statique (« partagée » en VB) membre de la classe dans XAML
1

Il 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éfinir les ressources statiques "Paramètres" dans mon Application.Resources de les 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 sois différent; en C#, vous accédez aux paramètres de l'application dans votre application via

DefaultNamespace.Properties.Settings.Default.ASettingValue 
1

<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 pour me aider à atteindre un "Aha!" moment :-) ... j'espère qu'après avoir passé plus de temps dans WPF je comprendrai pourquoi cela fonctionne.

+3

Que diriez-vous marquer une réponse comme « réponse »? :) –

+0

Il ya peut-être une meilleure réponse ici, mais cela fait deux ans que le problème était frais dans mon esprit et je travaille rarement avec WPF maintenant. donc je vais marquer mon dernier post ici comme réponse. –

+3

WTF ??? Pourquoi ne pas simplement marquer la réponse d'Enrico comme réponse au lieu de la copier et de marquer votre propre réponse? Voler est mauvais, M'kay ?! – Dimitri

3

J'ai une solution plus simple pour cela, en utilisant 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# pour cette extension de balisage sur mon blog ici: http://www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/

0

Vous pouvez également enregistrer la liste en tant que chaîne délimitée dans les paramètres Ensuite, utilisez 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); 
} 
} 

Puis, 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(); 
Questions connexes