[英]Binding to an IEnumerable<object> dependency property
我創建了一個名為SearchableCheckBoxList
的自定義控件(派生自UserControl
)。 在這個控件中,我有一個ItemsControl
,它包含Entry
類型的Items,如下所示:
public class Entry : BindableBase
{
public Entry(object content)
: this(content, false)
{ }
public Entry(object content, bool isChecked)
{
Content = content;
IsChecked = isChecked;
}
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set { this.SetProperty(ref this._isChecked, value); }
}
private object _content;
public object Content
{
get { return _content; }
set { SetProperty(ref _content, value); }
}
}
在我的代碼背后,我還有一個名為ItemsSource
(類型為IEnumerable
)的DependencyProperty
,它接受一組項目(任何類型)並將它們轉換為Entry
類型。 也就是說,對於集合中的每個元素,我正在創建一個新的Entry項並將該元素存儲在Entry項的Content屬性中,如下所示:
foreach (var item in ItemsSource)
itemsControl.Items.Add(new Entry(item));
我這樣做是因為在我的ItemsControl
,每個項目旁邊都有一個復選框,用戶可以單擊一個或多個復選框來選擇多個項目,這些項目將反映每個Entry
項目的IsChecked屬性。
我的代碼后面有另一個依賴屬性,名為SelectedItems
,定義如下:
public IEnumerable<object> SelectedItems
{
get { return (IEnumerable<object>)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
}
public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IEnumerable<object>), typeof(SearchableCheckBoxList),
new PropertyMetadata(default(IEnumerable<object>)));
每次在我的itemscontrol中選中或取消選中某個項目時,我都會更新上述DP:
private void checkBox_CheckChanged(object sender, RoutedEventArgs e)
{
var checkBox = (CheckBox)sender;
// Get entry from the content presenter
var entry = ((Entry)(((ContentPresenter)checkBox.Content).DataContext));
// Set its checked value based on the checkbox's checked value
entry.IsChecked = (bool)checkBox.IsChecked;
// Update selected items collection
SelectedItems = itemsControl.Items.Cast<Entry>().Where(i => i.IsChecked).Select(i => i.Content).ToList();
}
在我的主程序中,我正在使用此控件:
<controls:SearchableCheckBoxList SelectedItems="{Binding SelectedCities, Mode=TwoWay}"
ItemsSource="{Binding CityCollection, Mode=OneTime}"/>
在我的viewmodel中, SelectedCities
和CityCollection
定義如下:
private ObservableCollection<CityModel> _cityCollection;
public ObservableCollection<CityModel> CityCollection
{
get { return _cityCollection; }
set { SetProperty(ref _cityCollection, value); }
}
private List<object> _selectedCities = new List<object>();
public List<object> SelectedCities
{
get { return _selectedCities; }
set { SetProperty(ref _selectedCities, value); }
}
控件看起來像這樣 。
現在,所有這些工作正常,綁定正在按預期更新。 我遇到的問題是,為了工作,必須將SelectedCities定義為List<object>
。 我想將SelectedCities定義為List<CityModel>
,但是如果我這樣做,我的屬性的setter總是被調用,值為null。 我似乎無法弄清楚為什么或做什么。
編輯根據要求,這里是SearchableCheckBoxList.xaml和SearchableCheckBoxList.cs
我相信你的問題是C#中的集合不是協變的 。 我的意思是你不能將List<Person>
為List<object>
ie
class Program
{
static void Main(string[] args)
{
List<object> foo = new List<object>();
List<Person> bar = new List<Person>();
List<object> some = (List<object>) bar;
}
class Person { }
}
上面的程序將無法編譯。 您的程序編譯,因為轉換是通過“ SetProperty
”方法間接發生的。
我認為您應該使用泛型或者創建List<IBaseClass>
的集合而不是“ List<object>
”,並確保所有模型都繼承自IBaseClass
UPDATE
還有一種方法 - 使您的DP屬性類型成為對象。 對於團隊中的其他開發人員來說,如果有的話可能會讓人感到困惑。 如果您的DP中有某些邏輯,則必須手動檢查類型並進行轉換
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var control = new myUserControl();
myPersons = new List<Person>() { new Person() { Name = "some" } };
control.SetBinding(myUserControl.MyPropertyProperty, new Binding() { Source = MyPersons });
}
private List<Person> myPersons { get; set; }
public List<Person> MyPersons { get { return myPersons; } set { myPersons = value; } }
}
public class Person { public string Name; }
public class myUserControl : UserControl
{
public object MyProperty
{
get { return (object)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(object), typeof(myUserControl), new PropertyMetadata(0));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.