[英]Retrieve the string value of a WPF ComboBox’s selected item in the code behind
我在后面的代碼中檢索WPF ComboBox的選定項的字符串值時遇到麻煩。
我已經設置了三種不同類型的數組,它們為三個ComboBox提供了ItemSources。 我已經將每個ComboBox選定的項目綁定到名為DataBase的類的屬性。 我通過將每個DataBase屬性的值回顯到TextBox來驗證綁定是否有效。
在后面的代碼中,我想檢索每個ComboBox的選定項目的字符串值。 我可以為systemComboBox做到這一點,其中SelectedItem和SelectedValue都返回所選項目的字符串值。
我無法使它適用於SelectedItem和SelectedValue返回“ ComboBoxes.OneD”的oneDComboBox或正確返回SelectedValue但返回“ ComboBoxes.TwoD”作為SelectedItem值的twoDComboBox
誰能告訴我如何獲取oneDComboBox和twoDComboBox選定項的字符串值?
在Visual Studio中,我已將Assembly下面的代碼的Output Type設置為“ Console Application”,以便可以寫入控制台。
WPF
<Window x:Class="ComboBoxes.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ComboBoxes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Width="1200" Height="450"
mc:Ignorable="d">
<Window.Resources>
<x:Array x:Key="OneDArray" Type="{x:Type local:OneD}">
<local:OneD OneDName="OneD-0" />
<local:OneD OneDName="OneD-1" />
<local:OneD OneDName="OneD-2" />
<local:OneD OneDName="OneD-3" />
<local:OneD OneDName="OneD-4" />
</x:Array>
<x:Array x:Key="TwoDArray" Type="{x:Type local:TwoD}">
<local:TwoD TwoDName="TwoD-0" TwoDNumber="0" />
<local:TwoD TwoDName="TwoD-1" TwoDNumber="1" />
<local:TwoD TwoDName="TwoD-2" TwoDNumber="2" />
<local:TwoD TwoDName="TwoD-3" TwoDNumber="3" />
<local:TwoD TwoDName="TwoD-4" TwoDNumber="4" />
</x:Array>
<x:Array x:Key="SystemStringArray" Type="sys:String">
<sys:String>SystemString-0</sys:String>
<sys:String>SystemString-1</sys:String>
<sys:String>SystemString-2</sys:String>
<sys:String>SystemString-3</sys:String>
<sys:String>SystemString-4</sys:String>
</x:Array>
</Window.Resources>
<Grid>
<Grid.Resources>
<local:DataBase x:Key="dataBase" />
</Grid.Resources>
<Grid.DataContext>
<Binding Source="{StaticResource dataBase}" />
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="auto" />
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Label Grid.Row="1" Grid.Column="1" Content="OneDComboBox:" HorizontalAlignment="Right"/>
<ComboBox x:Name="oneDComboBox" Grid.Row="1" Grid.Column="2" Width="120" DisplayMemberPath="OneDName"
ItemsSource="{StaticResource OneDArray}"
SelectedItem="{Binding Path=DataBaseOneDName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
SelectionChanged="ComboBox_SelectionChanged"
/>
<Label Grid.Row="1" Grid.Column="4" Content="SystemComboBox:" HorizontalAlignment="Right"/>
<ComboBox x:Name="systemComboBox" Grid.Row="1" Grid.Column="5" Width="120"
ItemsSource="{StaticResource SystemStringArray}"
SelectedItem="{Binding Path=DataBaseSystemString, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
SelectionChanged="ComboBox_SelectionChanged"
/>
<Label Grid.Row="1" Grid.Column="7" Content="TwoDComboBox:" HorizontalAlignment="Right"/>
<ComboBox x:Name="twoDComboBox" Grid.Row="1" Grid.Column="8" Width="120" DisplayMemberPath="TwoDName"
ItemsSource="{Binding Source={StaticResource TwoDArray}}"
SelectedValue="{Binding Path=DataBaseTwoDNumber, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
SelectedValuePath="TwoDNumber" SelectionChanged="ComboBox_SelectionChanged"
/>
</Grid>
<Grid Grid.Row="3" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Label Grid.Row="2" Grid.Column="1" Content="BoundOneDName:" HorizontalAlignment="Right"/>
<TextBox x:Name="oneDComboBoxEcho" Grid.Row="3" Grid.Column="2" Width="120"
Text="{Binding Path=DataBaseOneDName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
TextWrapping="Wrap" />
<Label Grid.Row="2" Grid.Column="4" Content="BoundSystemString:" HorizontalAlignment="Right"/>
<TextBox x:Name="systemComboBoxEcho" Grid.Row="5" Grid.Column="5" Width="120"
Text="{Binding Path=DataBaseSystemString, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
TextWrapping="Wrap" />
<Label Grid.Row="2" Grid.Column="7" Content="BoundTwoDNumber:" HorizontalAlignment="Right"/>
<TextBox x:Name="twoDComboBoxEcho" Grid.Row="5" Grid.Column="8" Width="120"
Text="{Binding Path=DataBaseTwoDNumber, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
TextWrapping="Wrap" />
</Grid>
</Grid>
</Window>
C#
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace ComboBoxes
{
/// <summary>
/// Interaction logic for MainWindow.xaml
///
/// The code below reflects the suggestions made by:
/// 1 Ben Broadley (to use e.AddedItems[0]) and Benny (To look in the ItemsSource object) in the responses to https://stackoverflow.com/questions/4351603/get-selected-value-from-combo-box-in-c-sharp-wpf.
/// 2 Adam Nathan in the FAQ box on page 266 of his book "WPF 4.5 Unleashed".
///
///
///
/// </summary>
public partial class MainWindow : Window
{
//public MainWindow mainWindow;
DataBase dataBase;
public MainWindow()
{
InitializeComponent();
dataBase = new DataBase();
//DataContext = this;
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0) // Test to ensure that an item has been selected.
{
ComboBox sourceComboBox = (ComboBox)sender;
int selectedIndex = -1;
string selectedItem = "???";
string selectedValue = "???";
string displayMemberPath = "???";
if (sourceComboBox.Name == "oneDComboBox")
{
// Because this ComboBox.ItemsSource is bound to an array of types the selected value has to be unbundled from the selected type.
if (oneDComboBox.SelectedValue is OneD) // Verify ComboBox.ItemsSource is bound to what we think its bound to.
{
selectedIndex = sourceComboBox.SelectedIndex;
selectedItem = sourceComboBox.SelectedItem.ToString();
selectedValue = (oneDComboBox.SelectedValue as OneD).OneDName;
displayMemberPath = sourceComboBox.DisplayMemberPath.ToString();
}
}
else
if (sourceComboBox.Name == "systemComboBox")
{
selectedIndex = sourceComboBox.SelectedIndex;
selectedItem = sourceComboBox.SelectedItem.ToString();
selectedValue = sourceComboBox.SelectedValue.ToString();
displayMemberPath = sourceComboBox.DisplayMemberPath.ToString();
}
else
if (sourceComboBox.Name == "twoDComboBox")
{
// Because this ComboBox.ItemsSource is bound to an array of types the selected value has to be unbundled from the selected type.
if (e.AddedItems[0] is TwoD) // Verify ComboBox.ItemsSource is bound to what we think its bound to.
{
selectedIndex = sourceComboBox.SelectedIndex;
selectedItem = sourceComboBox.SelectedItem.ToString();
selectedValue = (e.AddedItems[0] as TwoD).TwoDName;
//selectedValue = (twoDComboBox.SelectedValue as TwoD).TwoDName; // Why doesn't this work? It works for oneDComboBox.
displayMemberPath = sourceComboBox.DisplayMemberPath.ToString();
}
}
Console.WriteLine($"\nComboBox Name = {sourceComboBox.Name}");
Console.WriteLine($"Selected Index = {selectedIndex} Selected Item = {selectedItem} Selected Value = {selectedValue} DisplayMemberPath = {displayMemberPath}");
}
}
}
public partial class DataBase : INotifyPropertyChanged
{
private string _dataBaseOneDName = "OneDArray";
public string DataBaseOneDName
{
get { return _dataBaseOneDName; }
set
{
if (_dataBaseOneDName != value)
{
_dataBaseOneDName = value;
NotifyPropertyChanged("DataBaseOneDName");
}
}
}
private string _dataBaseSystemString = "System_String";
public string DataBaseSystemString // String property used in binding examples.
{
get { return _dataBaseSystemString; }
set
{
if (_dataBaseSystemString != value)
{
_dataBaseSystemString = value;
NotifyPropertyChanged("DataBaseSystemString");
}
}
}
private int _dataBaseTwoDNumber = 99;
public int DataBaseTwoDNumber
{
get { return _dataBaseTwoDNumber; }
set
{
if (_dataBaseTwoDNumber != value)
{
_dataBaseTwoDNumber = value;
NotifyPropertyChanged("DataBaseTwoDNumber");
}
}
} // Int property used in binding examples.
#region INotifyPropertyChanged Members
/// Need to implement this interface in order to get data binding
/// to work properly.
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public partial class OneD // This class supports the "OneDArray" in the XAML.
{
public string OneDName { get; set; }
}
public partial class TwoD // This class supports the "TwoDArray" in the XAML.
{
public int TwoDNumber { get; set; }
public string TwoDName { get; set; }
}
}
在XAML標記中將SelectedValuePath
屬性設置為OneDName
並將SelectedValue
值屬性綁定到DataBaseOneDName
:
<ComboBox x:Name="oneDComboBox" Grid.Row="1" Grid.Column="2" Width="120" DisplayMemberPath="OneDName"
ItemsSource="{StaticResource OneDArray}"
SelectedValuePath="OneDName"
SelectedValue="{Binding Path=DataBaseOneDName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
SelectionChanged="ComboBox_SelectionChanged"
/>
然后,將SelectedItem
轉換為OneD
,然后訪問其OneDName
屬性:
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox sourceComboBox = (ComboBox)sender;
int selectedIndex = sourceComboBox.SelectedIndex;
OneD oneD = sourceComboBox.SelectedItem as OneD;
if (oneD != null)
{
string name = oneD.OneDName;
}
string displayMemberPath = sourceComboBox.DisplayMemberPath.ToString();
}
TwoD
。
另一個選擇是重寫類的ToString()
方法,例如:
public partial class OneD
{
public string OneDName { get; set; }
public override string ToString()
{
return OneDName;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.