簡體   English   中英

在后面的代碼中檢索WPF ComboBox的選定項的字符串值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM