값 변환기가 포함 된 내 데이터비 딩은 작동하지 않습니다
-
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 창에서 항목 객체 목록 (List <item>)을 보유한 종속성 프로퍼티 (항목)를 선언 하고이 XAML 코드를 사용 하여이 종속성 프로퍼티에 바인딩하는 콤보 박스를 만듭니다.
<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 메소드가 이제 Item-Object 대신 첫 번째 매개 변수로 String-Object가 전달된다는 것입니다.
내가 뭘 잘못하고 있죠?
안부, 케네스
해결책
간단한 해결 방법은 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 인터페이스를 구현할 수 있습니다
- 또한 이름이 없거나 이름이 변경 될 때 읽기 전용 속성 및 화재 알림 이벤트를 구현할 수 있습니다.
공개 수업 항목 : 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"속성 만 바인딩 할 수 있습니다.
- 컨버터는 구현하기가 매우 복잡합니다
- 그리고 종속성 OBJECT 기반 클래스는 UI 목적으로 만 사용해야합니다.
Databinding을 사용하려면 컬렉션을 항목이 아닌 항목 소스에 할당해야합니다. 아마도이 문제를 해결할 것이라고 생각합니다.
제휴하지 않습니다 StackOverflow