【问题标题】:WPF Binding My.Settings collection to Combobox itemsWPF 将 My.Settings 集合绑定到 Combobox 项
【发布时间】:2010-09-17 07:33:01
【问题描述】:

我对 WPF 非常陌生,并且仍在尝试围绕 XAML 中的绑定。

我想用 my.settings 中的字符串集合的值填充组合框。我可以用这样的代码做到这一点:

Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings

...它的工作原理。

如何在我的 XAML 中执行此操作?有可能吗?

谢谢

【问题讨论】:

    标签: wpf binding


    【解决方案1】:

    是的,您可以(并且大部分情况下应该)在 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>
    

    注意以下几个方面:

    • 我们声明了一个带有前缀“p”的 XML 命名空间,它指向“Settings”类所在的 .NET 命名空间,以便在 XAML 中引用它
    • 我们使用标记扩展“{Binding}”在 XAML 中声明绑定
    • 我们使用标记扩展“Static”来表明我们希望在 XAML 中引用静态(VB 中的“shared”)类成员

    【讨论】:

      【解决方案2】:

      这是可能的。在 C# 中,我这样做(对于一个简单的布尔值):

      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
      

      【讨论】:

        【解决方案3】:

        知道了!

        <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。所以我会在这里标记我的最后一篇文章作为答案。
        • WTF???为什么不直接将 Enrico 的答案标记为答案,而不是复制它并标记您自己的答案?偷东西不好,好吧?!
        【解决方案4】:

        我有一个更简单的解决方案,使用自定义标记扩展。在你的情况下,它可以这样使用:

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

        【讨论】:

          【解决方案5】:

          您还可以将列表作为分隔字符串存储在设置中,然后使用转换器。

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

          【讨论】:

            猜你喜欢
            • 2012-01-27
            • 2010-09-23
            • 2014-11-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多