WPF Привязка коллекции My.Settings к элементам Combobox

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

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

Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings

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

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

Спасибо

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
20 891
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

да, вы можете (и должны по большей части) объявлять привязки в 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, в котором находится класс Settings, чтобы ссылаться на него в XAML.
  • Мы использовали расширение разметки "{Binding}", чтобы объявить привязку в XAML.
  • Мы использовали расширение разметки «Static», чтобы указать, что мы хотим сослаться на статический («общий» в VB) член класса в XAML.

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

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

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

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

Понятно!

<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, я пойму, почему это работает.

Здесь может быть лучший ответ, но прошло два года с тех пор, как эта проблема была свежа в моей голове, и я редко работаю с WPF сейчас. так что я отмечу здесь свой последний пост как ответ.

Ben Brandt 27.08.2010 22:51

Какого черта ??? Почему бы просто не пометить ответ Энрико как «Ответ» вместо того, чтобы копировать его и отмечать свой собственный ответ? Воровать - это плохо, понимаешь ?!

Dimitri 07.08.2011 08:50

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

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

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

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

Другие вопросы по теме