簡體   English   中英

帶有null值的WPF ComboBox SelectedValue綁定顯示為空白

[英]WPF ComboBox SelectedValue binding with null value shows up blank

嘗試將2個或更多Comboboxes SelectedValue綁定到屬性時出現問題,即null。 只有1個與此屬性綁定的組合框將顯示實際值。

下面是我的Xaml,我使用DataTemplate選擇一個Combobox來呈現viewModel。

XAML:

<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Test"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <DataTemplate DataType="{x:Type local:PropertyValueViewModel}">
        <ComboBox SelectedValue="{Binding Value}" ItemsSource="{Binding SelectableValues}" DisplayMemberPath="Description" SelectedValuePath="Value"/>
    </DataTemplate>
</Window.Resources>
<StackPanel>
    <Label Content="These uses template:"></Label>
    <ContentPresenter Content="{Binding ValueSelector}"></ContentPresenter>
    <ContentPresenter Content="{Binding ValueSelector}"></ContentPresenter>
    <ContentPresenter Content="{Binding ValueSelector}"></ContentPresenter>
</StackPanel>

而背后的代碼:

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        ValueSelector = new PropertyValueViewModel()
        {
            SelectableValues = new List<SelectableValue>()
            {
                new SelectableValue("NULL", null),
                new SelectableValue("1", 1)
            },
            Value = null
        };

        DataContext = this;
    }

    public static readonly DependencyProperty ValueSelectorProperty = DependencyProperty.Register(
        "ValueSelector", typeof(PropertyValueViewModel), typeof(MainWindow), new PropertyMetadata(default(PropertyValueViewModel)));

    public PropertyValueViewModel ValueSelector
    {
        get { return (PropertyValueViewModel)GetValue(ValueSelectorProperty); }
        set { SetValue(ValueSelectorProperty, value); }
    }
}

/// <summary>
/// My viewModel
/// </summary>
public class PropertyValueViewModel
{
    public object Value { get; set; }
    public object SelectableValues { get; set; }
}

/// <summary>
/// The items in the combobox
/// </summary>
public class SelectableValue
{
    public SelectableValue(string header, object value)
    {
        Value = value;
        Description = header;
    }

    public object Value { get; set; }

    public string Description { get; set; }
}

現在我想知道為什么只有其中一個可以在啟動時顯示NULL值? 我可以更改其中任何一個的值,它們都會與屬性中的值同步 - 如果我選擇1然后再返回NULL,它們都將顯示為NULL。 似乎只有初始值沒有正確顯示。

如果我避免使用DataTemplate,綁定也會起作用。 有誰知道DAtaTemplate為什么會這樣?

有趣的問題。

從根本上說,這似乎是由您選擇使用null作為可選值之一。 當然,對於C#,.NET和WPF, null具有特殊含義。 該問題還涉及完成ComboBox元素初始化的順序。 SelectedValuePath屬性在SelectedValue屬性之后初始化。

這意味着當您的程序啟動並且創建了ComboBox元素時,當通過其綁定將null賦值給SelectedValue屬性時, ComboBox還沒有足夠的信息來處理該值作為合法項目選擇。 相反,它將其解釋為根本沒有選擇。

為什么最后一個 ComboBox仍然按照你想要的方式進行初始化? 我不太確定......我沒有對此進行過很長時間的調查。 我可以推測,但我的猜測正確的幾率似乎很低,所以我不會打擾。 因為它是異常的並且不一定與預期行為一致(基於上述,即使行為是期望的行為),我將把它歸結為WPF的許多“怪癖”之一。 :)

我找到了幾個解決這個問題的方法:

  • 不要將null用作可選值。 如果每個可選值都為非null,則保留用於初始化每個元素的SelectedValue屬性的非null值,並且在初始化SelectedValuePath時,正確設置ComboBox的當前選擇。
  • 不要使用SelectedValuePath 相反,只需綁定到SelectedItem並使用所需的SelectableValue類實例(例如列表中的第一個)初始化Value屬性。
  • ComboBoxLoaded事件中,刷新綁定的目標。

前兩個與您當前的設計有很大不同。 就個人而言,如果可能的話,我會選擇其中一個。 在我看來,使用null作為ComboBox的可選值存在明顯的危險,這可能不是您遇到的唯一奇怪之處。 從長遠來看,如果繼續使用null ,維護這部分代碼可能會花費更多。

也就是說,第三個選項確實有效,如果你很幸運,使用null的唯一真正危險就是初始化。 我建議的解決方案的解決方案看起來像這樣:

XAML:

<DataTemplate DataType="{x:Type local:PropertyValueViewModel}">
    <ComboBox SelectedValue="{Binding Value}"
              ItemsSource="{Binding SelectableValues}"
              DisplayMemberPath="Description"
              SelectedValuePath="Value"
              Loaded="comboBox_Loaded"/>
</DataTemplate>

C#:

private void comboBox_Loaded(object sender, RoutedEventArgs e)
{
    ComboBox comboBox = (ComboBox)e.OriginalSource;

    BindingOperations.GetBindingExpression(comboBox, ComboBox.SelectedValueProperty)
                     .UpdateTarget();
}

這會強制WPF更新目標(即控件的SelectedValue屬性)。 此時,已設置SelectedValuePath ,此時為屬性分配null ,正確更新ComboBox的選定項。


順便說一句,我強烈建議您消除模型中Value屬性的名稱。 在單個XAML元素中使用兩個不同的Value屬性進行綁定非常令人困惑。 我將分別為PropertyValueViewModel類和SelectableValue類使用SelectedValueItemValue

暫無
暫無

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

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