لا تعمل البيانات الخاصة بي مع محول القيمة
-
20-08-2019 - |
سؤال
لدي فئة عنصر بسيطة ، يبدو ذلك:
public class Item : DependencyObject
{
public int No
{
get { return (int)GetValue(NoProperty); }
set { SetValue(NoProperty, value); }
}
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
public static readonly DependencyProperty NoProperty = DependencyProperty.Register("No", typeof(int), typeof(Item));
public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Item));
}
و ValueConverter ، هذا يبدو هكذا:
[ValueConversion(typeof(Item), typeof(string))]
internal class ItemToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
var item = ((Item)value);
var sb = new StringBuilder();
sb.AppendFormat("Item # {0}", item.No);
if (string.IsNullOrEmpty(item.Name) == false)
{
sb.AppendFormat(" - [{0}]", item.Name);
}
return sb.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
في نافذة WPF الخاصة بي ، أعلنت عن وجود DependencyProperty (تسمى العناصر) التي تحتوي على قائمة كائنات العناصر (القائمة <Item>) وإنشاء combobox يرتبط بهذا الاعتماد باستخدام هذا xaml-code:
<ComboBox ItemsSource="{Binding ElementName=mainWindow, Path=Items}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource itemToStringConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
إذا قمت بتنفيذ الكود أدناه مرة واحدة ، فإن بيانات البيانات تعمل بشكل جيد ، فالفشل في تحويل القيمة إذا قمت بتنفيذها مرة أخرى:
var item1 = new Item {Name = "Item A", No = 1};
var item2 = new Item {Name = "Item B", No = 2};
var item3 = new Item {Name = "Item C", No = 3};
Items = new List<Item> {item1, item2, item3};
المشكلة هي أن طريقة itemToStringConverter.convert تم تمريرها الآن ككائن سلسلة كمعلمة أول بدلاً من كائن عنصر؟
ما الخطأ الذي افعله؟
التحيات ، كينيث
المحلول
سيكون الحل البديل هو التحقق من النوع الذي تم تمريره إلى ValueConverter. تغيير طريقة تحويل على النحو التالي:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
var item = value as Item;
if(item == null) { return null; }
var sb = new StringBuilder();
sb.AppendFormat("Item # {0}", item.No);
if(string.IsNullOrEmpty(item.Name) == false) {
sb.AppendFormat(" - [{0}]", item.Name);
}
return sb.ToString();
}
نصائح أخرى
طريقه بديله،
- يمكنك استخلاص فصلك من الكائن بدلاً من الاعتماد على
- يمكنك تنفيذ واجهة InotifyPropertyChange
- ويمكنك تنفيذ حدث قراءة فقط وإخطار الحريق عندما يتغير أي من NO أو الاسم.
عنصر الفئة العامة: System.componentModel.InotifyPropertyChanged {
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private void Notify(string p)
{
if (PropertyChanged != null)
PropertyChanged(this,
new System.ComponentModel.PropertyChangedEventArgs(p));
}
private int _No = 0;
public int No
{
get
{
return _No;
}
set
{
_No = value;
Notify("No");
Notify("DisplayName");
}
}
private string _Name = "";
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
Notify("Name");
Notify("DisplayName");
}
}
public string DisplayName
{
get
{
string sb = string.Format("Item # {0}", _No);
if (!string.IsNullOrEmpty(_Name))
sb += _Name;
return sb;
}
}
}
الآن يمكنك فقط ربط خاصية "DisplayName" بدلاً من المحول ..
- المحولات معقدة جدا للتنفيذ
- وينبغي استخدام الفئات القائمة على الاعتماد فقط لأغراض واجهة المستخدم
إذا كنت ترغب في استخدام DataBinding ، فيجب عليك تعيين مجموعتك إلى العناصر ، وليس العناصر. أعتقد أن هذا من شأنه أن يصلح هذه المشكلة.