2010-01-08 5 views
0

문제 : 표시하려고하는 데이터는 본질적으로 개체의 컬렉션 모음입니다. 따라서 행은 숫자, 데이터 격자의 일반 수 있으며 열은 임의의 수입니다. DataGrid에서는 그리 정상적이지 않습니다. 일반적으로 열 개수가 설정되어 있고 행이 다릅니다. DataGrid 셀은 문자열이거나 콤보 박스를 통해 변경 가능한 값입니다.Silverlight DataGrid - 개체 컬렉션의 컬렉션에 바인딩

시도 솔루션 : 동적으로 DataGrid에 열을 추가하려고 시도했습니다. 코드 랭귀지에서 추가하는 것만으로도 효과적 이었지만 실제 문제는 밑에있는 객체에 바인딩하는 것이 었습니다. 데이터가 동적으로 빌드되고 몇 가지 형식을 시도했습니다. 나는 배열의 컬렉션과 ObservableCollections의 ObservableCollection을 시도했다. 개체에 바인딩 할 수 있지만 Silverlight의 바인딩이 속성에 바인딩해야하므로 데이터를 이런 식으로 표시하는 솔루션을 만들 수 없습니다.

결과적으로 필자의 해결책은 목록 및 데이터 격자를 사용하여보다 전통적인 방식으로 데이터를 표시하는 것이 었습니다. 목록에서 항목을 선택하면 DataGrid의 데이터가 다시 채워져서 개체가 표시됩니다.

질문 : 개체 컬렉션에 DataGrid 셀을 바인딩하는 방법이 있습니까?

이 질문 (WPF)이 비슷해 보이지만 어떤 도움도되지 않았습니다. 나는 그것이 같은 문제라고 생각한다. WPF DataGrid: DataGridComboxBox ItemsSource Binding to a Collection of Collections

답변

0

나는 당신이 성취하고자하는 것을 이해하고 있으며, 실제로 당신의 문제에 더 우아한 해결책을 가지고 있다고 생각하며 그것은 어떤 커스텀 클래스도 쓰지 않는다. 나는이 문제에 관한 블로그 포스트를 썼다. 이 블로그는 Silverlight Toolkit의 DataGrid를 대상으로하지만 쉽게 수정할 수있어 모든 그리드를 사용할 수 있습니다.

The solution is here.

이 당신이 찾고 있던 무슨 경우 알려주세요.

+0

나는 읽기가 있었고 그 해결책은 정말 우아한 것처럼 보였다. 템플릿 문자열에서했던 것처럼 컬렉션에 바인딩 할 수 있다는 것을 몰랐습니다. 즉 Text = '{{바인딩 기간 [{0}]. {1}}}' WPF로 제한되어 Silverlight에서 그럴 수 없다고 생각했습니다. 나는 더 조사 할 것이다. 감사! –

1

단순한 컬렉션을 내부 개체로 사용하는 대신 컬렉션에서 파생 된 클래스를 만들고 ICustomTypeDescriptor을 구현하십시오. 인터페이스 구현에서 컬렉션의 요소를 반복하고 이에 따라 속성 설명자 컬렉션을 채 웁니다. 일단 그렇게하면 XAML의 속성에 바인딩 할 수 있어야합니다.

예 - 당신은 키 이름 (내가 한 줄에 압축 된 모든 사소한 메소드 구현)에 결합 할 수있는 사전을 기반으로 데이터 객체 : 뒤에 코드에서

class DictionaryDataObject : Dictionary<string, object>, ICustomTypeDescriptor 
{ 
    #region ICustomTypeDescriptor Members 

    public AttributeCollection GetAttributes() { return AttributeCollection.Empty; } 
    public string GetClassName() { return "DictionaryDataObject"; } 
    public string GetComponentName() { return null; } 
    public TypeConverter GetConverter() { return null; } 
    public EventDescriptor GetDefaultEvent() { return null; } 
    public PropertyDescriptor GetDefaultProperty() { return null; } 
    public object GetEditor(Type editorBaseType) { return null; } 
    public EventDescriptorCollection GetEvents(Attribute[] attributes) { return EventDescriptorCollection.Empty; } 
    public EventDescriptorCollection GetEvents() { return EventDescriptorCollection.Empty; } 
    public PropertyDescriptorCollection GetProperties() { return GetProperties(null); } 
    public object GetPropertyOwner(PropertyDescriptor pd) { return this; } 

    public PropertyDescriptorCollection GetProperties(Attribute[] attributes) 
    { 
     var pds = 
      this.Keys 
      .Select(x => new DictionaryPropertyDescriptor(x)) 
      .ToArray(); 
     return new PropertyDescriptorCollection(pds); 
    } 

    #endregion 
} 

class DictionaryPropertyDescriptor : PropertyDescriptor 
{ 
    public DictionaryPropertyDescriptor(string name) : base(name, null) { } 
    public override bool CanResetValue(object component) { return false; } 
    public override Type ComponentType { get { return null; } } 
    public override bool IsReadOnly { get { return false; } } 
    public override Type PropertyType { get { return typeof(object); } } 
    public override void ResetValue(object component) { } 
    public override bool ShouldSerializeValue(object component) { return false; } 

    public override object GetValue(object component) 
    { 
     var dic = component as DictionaryDataObject; 
     if (dic == null) return null; 
     return dic[Name]; 
    } 

    public override void SetValue(object component, object value) 
    { 
     var dic = component as DictionaryDataObject; 
     if (dic == null) return; 
     dic[Name] = value; 
    } 
} 

샘플 객체 설정 :

DictionaryDataObject ddo = new DictionaryDataObject(); 

public Window4() 
{ 
    ddo["propa"] = 1; 
    ddo["propb"] = "foo"; 
    ddo["propc"] = "bar"; 
    ddo["propd"] = 4.5; 
    InitializeComponent(); 
    DataContext = ddo; 
} 

XAML 사용 : 당신이 ADAP하려는 경우

<Window.Resources> 
    <DataTemplate x:Key="template"> 
     <WrapPanel> 
      <TextBlock Text="{Binding propa}" Margin="5"/> 
      <TextBlock Text="{Binding propb}" Margin="5"/> 
      <TextBlock Text="{Binding propc}" Margin="5"/> 
      <TextBlock Text="{Binding propd}" Margin="5"/> 
     </WrapPanel> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <ContentControl Content="{Binding}" ContentTemplate="{StaticResource template}"/> 
</Grid> 

이 솔루션을 사전 대신 목록에 추가하려면 목록 요소의 일부 속성을 기반으로 각 속성 이름을 설정해야합니다.

+0

감사합니다.이 문제를 해결해 드리겠습니다. 아직도 내가 원하는 것보다 조금 더 복잡해 보이지만, 해결 방법이 있다는 것을 알기에 좋다면. 건배 –

관련 문제