WPF Binding Коллекция My.Settings для элементов Combobox - PullRequest
8 голосов
/ 15 октября 2008

Я ОЧЕНЬ новичок в WPF и все еще пытаюсь обернуть голову связыванием в XAML.

Я бы хотел заполнить комбинированный список значениями коллекции строк в my.settings. Я могу сделать это в коде, как это:

Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings

... и это работает.

Как я могу сделать это в моем XAML? это возможно?

Спасибо

Ответы [ 5 ]

18 голосов
/ 15 октября 2008

Да , вы можете (и должны по большей части) объявлять привязки в XAML, поскольку это одна из самых мощных функций в WPF.

В вашем случае, чтобы привязать ComboBox к одной из ваших пользовательских настроек, вы должны использовать следующий XAML:

<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>

Обратите внимание на следующие аспекты:

  • Мы объявили пространство имен XML с префиксом «p», которое указывает на пространство имен .NET, где находится класс «Настройки», чтобы ссылаться на него в XAML
  • Мы использовали расширение разметки '{Binding}', чтобы объявить привязку в XAML
  • Мы использовали расширение разметки «Static», чтобы указать, что мы хотим сослаться на член класса static («shared» в VB) в XAML
3 голосов
/ 30 апреля 2009

У меня есть более простое решение для этого, используя пользовательское расширение разметки. В вашем случае это можно использовать так:

<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>

Вы можете найти код C # для этого расширения разметки в моем блоге здесь: http://www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/

1 голос
/ 15 октября 2008

Понял!

<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>

Спасибо всем за помощь в достижении великолепного "Ага!" момент :-) ... надеюсь, после того, как я проведу больше времени в WPF, я пойму, почему это работает.

1 голос
/ 15 октября 2008

Это возможно. В C # я делаю это так (для простого bool):

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

Я определяю статический ресурс «Настройки» в приложении App.xaml следующим образом:

<!-- 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>

Ваш путь может быть другим; в C # вы получаете доступ к настройкам приложения в вашем приложении через

DefaultNamespace.Properties.Settings.Default.ASettingValue
0 голосов
/ 06 ноября 2009

Вы также можете сохранить список в виде строки с разделителями в настройках, а затем использовать конвертер.

<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);
 }
}

Затем, когда нажата кнопка обзора, вы можете добавить в список:

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...