UWP 组合框绑定到 SelectedItem 属性
Posted
技术标签:
【中文标题】UWP 组合框绑定到 SelectedItem 属性【英文标题】:UWP Combobox binding to SelectedItem property 【发布时间】:2016-02-22 15:28:55 【问题描述】:我正在尝试让组合框与绑定一起使用,以便最终可以将其用于某些设置。我可以从可观察的集合中获取要填充的项目并将“SelectedItem”绑定到属性SelectedItem="x:Bind SelectedComboBoxOption"
但是当我更改选择时,这并没有反映在文本框中也绑定到这个属性。在它后面的代码中,它在启动时设置属性一次,但在更改组合框中的项目时不设置。我一定错过了一些东西,但我不清楚是什么。有什么想法吗?
这是 XAML:
<Page
x:Class="ComboBoxTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ComboBoxTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
<StackPanel>
<ComboBox
Name="ComboBox"
ItemsSource="x:Bind ComboBoxOptions"
SelectedItem="x:Bind SelectedComboBoxOption, Mode=TwoWay"
SelectedValuePath="ComboBoxOption"
DisplayMemberPath="ComboBoxHumanReadableOption"
Header="ComboBox" >
</ComboBox>
<TextBlock Name="BoundTextblock" Text="x:Bind SelectedComboBoxOption"/>
</StackPanel>
</Grid>
这是背后的代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace ComboBoxTest
public sealed partial class MainPage : Page, INotifyPropertyChanged
private ObservableCollection<ComboBoxItem> ComboBoxOptions;
public MainPage()
this.InitializeComponent();
ComboBoxOptions = new ObservableCollection<ComboBoxItem>();
ComboBoxOptionsManager.GetComboBoxList(ComboBoxOptions);
public class ComboBoxItem
public string ComboBoxOption get; set;
public string ComboBoxHumanReadableOption get; set;
public class ComboBoxOptionsManager
public static void GetComboBoxList(ObservableCollection<ComboBoxItem> ComboBoxItems)
var allItems = getComboBoxItems();
ComboBoxItems.Clear();
allItems.ForEach(p => ComboBoxItems.Add(p));
private static List<ComboBoxItem> getComboBoxItems()
var items = new List<ComboBoxItem>();
items.Add(new ComboBoxItem() ComboBoxOption = "Option1", ComboBoxHumanReadableOption = "Option 1" );
items.Add(new ComboBoxItem() ComboBoxOption = "Option2", ComboBoxHumanReadableOption = "Option 2" );
items.Add(new ComboBoxItem() ComboBoxOption = "Option3", ComboBoxHumanReadableOption = "Option 3" );
return items;
string _SelectedComboBoxOption = "Option1";
public string SelectedComboBoxOption
get
return _SelectedComboBoxOption;
set
if (_SelectedComboBoxOption != value)
_SelectedComboBoxOption = value;
RaisePropertyChanged("SelectedComboBoxOption");
void RaisePropertyChanged(string prop)
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop));
public event PropertyChangedEventHandler PropertyChanged;
【问题讨论】:
【参考方案1】:默认情况下,x:Bind
设置为 OneTime
。您只需将模式设置为 OneWay
即可解决此问题。
Text="x:Bind SelectedComboBoxOption, Mode=OneWay"
【讨论】:
不幸的是,这似乎没有什么不同。此外,由于我想最终加载首选项并将其反映在组合框中,我不应该使用:'Mode=TwoWay' 吗? @RonaldA For SelectedItem 保留Mode=TwoWay
但对于TextBlock
中的Text
属性,您必须使用Mode=OneWay
。【参考方案2】:
正如@Mike Eason 和@kubakista 所说,您需要明确设置Mode
。但这并不能完全解决您的问题。
在您的代码中,您的 SelectedComboBoxOption
是一个字符串,但 SelectedItem
是一个 ComboBoxItem
对象。将String
绑定到SelectedItem
不会更改ComboBox
的选定项。所以如果你想用SelectedComboBoxOption
来获取和设置ComboBox
的选中项,你需要把SelectedComboBoxOption
改成ComboBoxItem
,并在x:Bind
中使用Convert在Object
和ComboBoxItem
之间进行转换.
Convert 可能会喜欢:
public class ComboBoxItemConvert : IValueConverter
public object Convert(object value, Type targetType, object parameter, string language)
return value;
public object ConvertBack(object value, Type targetType, object parameter, string language)
return value as MainPage.ComboBoxItem;
XAML 可能会喜欢:
<Page ...>
<Page.Resources>
<local:ComboBoxItemConvert x:Key="ComboBoxItemConvert" />
</Page.Resources>
<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
<StackPanel>
<ComboBox Name="ComboBox"
DisplayMemberPath="ComboBoxHumanReadableOption"
Header="ComboBox"
ItemsSource="x:Bind ComboBoxOptions"
SelectedItem="x:Bind SelectedComboBoxOption, Mode=TwoWay, Converter=StaticResource ComboBoxItemConvert"
SelectedValuePath="ComboBoxOption" />
<TextBlock Name="BoundTextblock" Text="x:Bind SelectedComboBoxOption.ComboBoxHumanReadableOption, Mode=OneWay" />
</StackPanel>
</Grid>
</Page>
在代码隐藏中:
public sealed partial class MainPage : Page, INotifyPropertyChanged
private ObservableCollection<ComboBoxItem> ComboBoxOptions;
public MainPage()
this.InitializeComponent();
ComboBoxOptions = new ObservableCollection<ComboBoxItem>();
ComboBoxOptionsManager.GetComboBoxList(ComboBoxOptions);
SelectedComboBoxOption = ComboBoxOptions[0];
...
private ComboBoxItem _SelectedComboBoxOption;
public ComboBoxItem SelectedComboBoxOption
get
return _SelectedComboBoxOption;
set
if (_SelectedComboBoxOption != value)
_SelectedComboBoxOption = value;
RaisePropertyChanged("SelectedComboBoxOption");
...
如果您只想在TextBlock
中显示所选项目,有一个简单的方法。我们可以将TextBlock
的Text
属性绑定到ComboBox
的SelectedItem
。请注意SelectedItem
的类型是System.Object
,而x:Bind
是强类型,并且会解析路径中每个步骤的类型。如果返回的类型没有成员,它将在编译时失败。所以我们需要指定一个强制类型转换来告诉绑定对象的真实类型。但是在x:Bind
中有一个issue while cast 嵌套类。我们可以将ComboBoxItem
排除在MainPage
之外作为一种解决方法。
namespace ComboBoxTest
public class ComboBoxItem
public string ComboBoxOption get; set;
public string ComboBoxHumanReadableOption get; set;
public sealed partial class MainPage : Page, INotifyPropertyChanged
...
在 XAML 中:
<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
<StackPanel>
<ComboBox Name="ComboBox"
DisplayMemberPath="ComboBoxHumanReadableOption"
Header="ComboBox"
ItemsSource="x:Bind ComboBoxOptions"
SelectedValuePath="ComboBoxOption" />
<TextBlock Name="BoundTextblock" Text="x:Bind ComboBox.SelectedItem.(local:ComboBoxItem.ComboBoxHumanReadableOption), Mode=OneWay" />
</StackPanel>
</Grid>
【讨论】:
这很完美!也非常感谢您的精彩解释。作为一个新手,要理解为什么事情会以某种方式完成并不总是那么容易。 @Jay,我遇到了相反的问题。初始化后为空白,可以正常选择。请你看看这个问题好吗?谢谢! ***.com/questions/39090923/…【参考方案3】:另一个解决方案(更像 MVVM)是在您的代码隐藏中创建一个 ComboBoxItem 类型的对象,绑定到该对象,然后让您的代码隐藏操作该对象以获得所需的字符串。这将使您不必创建转换器:
C#
public ComboBoxItem ComboBoxItemSelected get; set;
XAML
SelectedItem = "Binding ComboBoxItemSelected, Mode=TwoWay"
【讨论】:
以上是关于UWP 组合框绑定到 SelectedItem 属性的主要内容,如果未能解决你的问题,请参考以下文章
Silverlight 组合框 SelectedItem 绑定问题
绑定组合框在(重新)填充数据源时更改 SelectedItem
如何使用 TwoWay 模式将 Listview SelectedItem 绑定到文本框?