簡體   English   中英

當 UWP ComboBox 中的“IsEditable”為真時,如何將輸入的文本顯示為 Combobox 選定項?

[英]How to show entered text as Combobox selected item when "IsEditable" is true in UWP ComboBox?

我想創建一個 ComboBox + TextBox,為此我嘗試在 ComboBox 中設置“IsEditable”為真。 我正在使用一組對象作為 ComboBox 的 ItemSource,它工作正常。 但是當我輸入任何文本時,它會顯示這個錯誤。

錯誤:BindingExpression 路徑錯誤:在“Windows.Foundation.IReference`1”上找不到“ComboBoxOption”屬性。 拋出異常:CBExample2.exe 中的“System.NullReferenceException”

我認為這個錯誤是因為當我在組合框中輸入文本時,它會將其作為未轉換回對象的字符串。

這是我的完整代碼。

主頁.xaml

<Page.Resources>
    <local:ComboBoxItemConvert x:Key="ComboBoxItemConvert" />
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <ComboBox Name="ComboBox"
                  DisplayMemberPath="ComboBoxHumanReadableOption"
                  Header="ComboBox"
                  IsEditable="True"
                  IsTextSearchEnabled="True"
                  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>

背后的代碼

public sealed partial class MainPage : Page, INotifyPropertyChanged
{

    private ObservableCollection<ComboBoxItem> ComboBoxOptions;
    public event PropertyChangedEventHandler PropertyChanged;
    public MainPage()
    {
        this.InitializeComponent();
        ComboBoxOptions = new ObservableCollection<ComboBoxItem>();
        ComboBoxOptionsManager.GetComboBoxList(ComboBoxOptions);
        SelectedComboBoxOption = ComboBoxOptions[0];
    }

    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;
        }
    }

    ComboBoxItem _SelectedComboBoxOption ;
    public ComboBoxItem 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 class ComboBoxItemConvert : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value.GetType().Equals(typeof(ComboBoxItem)))
        {
            return value;
        }
        return new ComboBoxItem() { ComboBoxOption = "new", ComboBoxHumanReadableOption = "new" }; 

    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value as MainPage.ComboBoxItem;
    }
}

我想要的是將輸入的文本添加為​​組合框中的新選項,輸入時應將其視為已選中。 請幫忙。 在過去的 4 天里,我一直被困在這一點上。 提前致謝。

錯誤的原因是轉換器沒有考慮null的情況。

請按照以下步驟操作:

  1. MainPage刪除了ComboBoxItemComboBoxOptionsManager類的定義並單獨定義了它們。

  2. 覆蓋ComboBoxItem的 Equal 方法以處理后續項目添加

public class ComboBoxItem
{
    public string ComboBoxOption { get; set; }
    public string ComboBoxHumanReadableOption { get; set; }

    public override bool Equals(object obj)
    {
        return obj is ComboBoxItem item &&
               ComboBoxOption == item.ComboBoxOption;
    }
}
  1. 修改ComboBoxItemConvert的結構並添加數據集
public class ComboBoxItemConvert : IValueConverter
{
    public ObservableCollection<ComboBoxItem> Options { get; set; }
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value !=null && value.GetType().Equals(typeof(ComboBoxItem)))
        {
            return value;
        }
        var newItem = new ComboBoxItem() { ComboBoxOption = "new", ComboBoxHumanReadableOption = "new" };
        if(Options!=null && !Options.Contains(newItem))
        {
            Options.Add(newItem);
        }
        return newItem;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value as ComboBoxItem;
    }
}

用法

<local:ComboBoxItemConvert x:Key="ComboBoxItemConvert" Options="{x:Bind ComboBoxOptions}" />

當您輸入一個不在默認數據集 ( ComboBoxOptions ) 中的項目並按Enter ,一個新的ComboBoxItem將作為所選項目添加到數據集中。


如果您需要輸入自定義文本並相應地生成新條目,則需要添加新內容。

主頁.xaml.cs

private string _editText;
public string EditText
{
    get => _editText;
    set { _editText = value; RaisePropertyChanged("EditText"); }
}

轉換器

...
public string ComboBoxEditText { get; set; }
...
public object Convert(object value, Type targetType, object parameter, string language)
{
    ...
    var newItem = new ComboBoxItem() { ComboBoxOption = ComboBoxEditText ?? "new", ComboBoxHumanReadableOption = ComboBoxEditText ?? "new" };
    if (Options != null && !Options.Contains(newItem))
    {
        Options.Add(newItem);
    }
    return newItem;
}

主頁.xaml

<Page.Resources>
    <local:ComboBoxItemConvert x:Key="ComboBoxItemConvert" Options="{x:Bind ComboBoxOptions}" ComboBoxEditText="{x:Bind EditText,Mode=OneWay}"/>
</Page.Resources>

...
<ComboBox Name="ComboBox"
      ...
      IsEditable="True"
      IsTextSearchEnabled="True"
      Text="{x:Bind EditText,Mode=TwoWay}"
      ...
      />
...

這將滿足您的要求。

此致。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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