2008-10-15 3 views
8

Я ОЧЕНЬ новичок в WPF и все еще пытаюсь обернуть голову вокруг привязки в XAML.WPF Binding My.Settings collection to Combobox items

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

Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings

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

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

Благодаря

ответ

18

Да, вы можете (и должны по большей части) объявить привязки в 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» для того, чтобы указать, что мы хотим, чтобы обратиться к статической («общий» в VB) член класса в XAML
1

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

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

Я определяю статический ресурс "Настройки" в Application.Resources моего 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 
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> 

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

+3

Как насчет маркировки один ответы, как «ответил»? :) – 2010-08-10 16:09:29

3

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

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

0

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

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