[英]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
屬性。 ComboBox
的Loaded
事件中,刷新綁定的目標。 前兩個與您當前的設計有很大不同。 就個人而言,如果可能的話,我會選擇其中一個。 在我看來,使用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
類使用SelectedValue
和ItemValue
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.