WPF 将 My.Settings 集合绑定到 Combobox 项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/204779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Binding My.Settings collection to Combobox items
提问by Ben Brandt
I'm VERY new to WPF, and still trying to wrap my head around binding in XAML.
我对 WPF 非常陌生,并且仍然试图围绕 XAML 中的绑定进行思考。
I'd like to populate a combobox with the values of a string collection in my.settings. I can do it in code like this:
我想用 my.settings 中字符串集合的值填充组合框。我可以在这样的代码中做到这一点:
Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings
Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings
...and it works.
...它有效。
How can I do this in my XAML? is it possible?
如何在我的 XAML 中执行此操作?是否可以?
Thanks
谢谢
回答by Enrico Campidoglio
Yes, you can (and should for the most part) declare bindings in XAML, since that's one of the most powerful features in WPF.
是的,您可以(并且在大多数情况下应该)在 XAML 中声明绑定,因为这是 WPF 中最强大的功能之一。
In your case, to bind the ComboBox to one of your custom settings you would use the following XAML:
在您的情况下,要将 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>
Notice the following aspects:
注意以下几个方面:
- We declared an XML namespace with the prefix 'p' that points to the .NET namespace where the 'Settings' class lives in order to refer to it in XAML
- We used the markup extension '{Binding}' in order to declare a binding in XAML
- We used the markup extension 'Static' in order to indicate that we want to refer to a static ('shared' in VB) class member in XAML
- 我们声明了一个带有前缀“p”的 XML 命名空间,它指向“设置”类所在的 .NET 命名空间,以便在 XAML 中引用它
- 我们使用标记扩展“{Binding}”来声明 XAML 中的绑定
- 我们使用标记扩展“Static”来指示我们想要引用 XAML 中的静态(VB 中的“共享”)类成员
回答by Thomas Levesque
I have a simpler solution for doing that, using a custom markup extension. In your case it could be used like this :
我有一个更简单的解决方案,使用自定义标记扩展。在你的情况下,它可以这样使用:
<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>
You can find the C# code for this markup extension on my blog here : http://www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/
您可以在我的博客上找到此标记扩展的 C# 代码:http: //www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/
回答by Thomas Levesque
It is possible. In C#, I do it like this (for a simple bool):
有可能的。在 C# 中,我是这样做的(对于一个简单的布尔值):
IsExpanded="{Binding Source={StaticResource Settings}, Mode=TwoWay, Path=Default.ASettingValue}"
I define the static resource "Settings" in my App.xaml's Application.Resources thusly:
我这样在 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>
Your path may be different; in C#, you access app settings in your application via
你的路径可能不同;在 C# 中,您可以通过以下方式访问应用程序中的应用程序设置
DefaultNamespace.Properties.Settings.Default.ASettingValue
回答by Ben Brandt
Got it!
知道了!
<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>
Thank you all for helping me reach a great "Aha!" moment :-) ...hopefully after I spend some more time in WPF I'll understand why this works.
感谢大家帮助我达到一个伟大的“啊哈!” 时刻:-) ...希望在我在 WPF 中花费更多时间后,我会理解为什么会这样。
回答by Echilon
You could also store the list as a delimited string in settings then use a converter.
您还可以将列表存储为设置中的分隔字符串,然后使用转换器。
<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);
}
}
Then when a browse button is clicked, you can add to the list:
然后,当单击浏览按钮时,您可以添加到列表中:
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();