문제

간단한 항목 클래스가 있습니다.

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();
    }

다른 팁

대체 접근법,

  1. 종속성 대신 객체에서 클래스를 도출 할 수 있습니다.
  2. InotifyPropertyChange 인터페이스를 구현할 수 있습니다
  3. 또한 이름이 없거나 이름이 변경 될 때 읽기 전용 속성 및 화재 알림 이벤트를 구현할 수 있습니다.

공개 수업 항목 : 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"속성 만 바인딩 할 수 있습니다.

  1. 컨버터는 구현하기가 매우 복잡합니다
  2. 그리고 종속성 OBJECT 기반 클래스는 UI 목적으로 만 사용해야합니다.

Databinding을 사용하려면 컬렉션을 항목이 아닌 항목 소스에 할당해야합니다. 아마도이 문제를 해결할 것이라고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top