2011-01-11 5 views
2

저는 WPF를 처음 사용하고 있으며 사용자 지정 개체 목록으로 ListView를 채우려는 경우 몇 가지 어려움이 있습니다.WPF 데이터 바인딩 문제

internal class ApplicationCode 
{ 
    public int Code { get; set; } 

    public IEnumerable<string> InstrumentCodes { get; set; } 
} 

ListView에 ItemsSource로 설정 한 ApplicationCode 목록이 있습니다. ApplicationCode.Code를 문자열로 표시하고 나머지 열에 대해서는 열 이름이 InstrumentCodes 컬렉션에 포함되어 있는지 여부에 따라 선택/선택 해제 할 수있는 확인란을 표시해야합니다. 나는 데이터 바인딩에 변환기를 사용 확인란을 설정하기 위해

: 나는 바인딩 셀 데이터의 시점에서 현재 열이 알고 내가 할 수 없기 때문에

<DataTemplate x:Key="InstrumentCodeTemplate"> 
    <CheckBox IsEnabled="False" IsChecked="{Binding Mode=OneTime, Converter={StaticResource InstrumentSelectionConverter}}" /> 
</DataTemplate> 

내가 가진 문제는 ConverterParameter를 설정할 수 없습니다.

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    ApplicationCode appCode = value as ApplicationCode; 

    return appCode != null && appCode.InstrumentCodes.Contains(parameter.ToString()); 
} 

작은 예 :

Id | Code1 | Code3 | Code4 
-------------------------------- 
    123 | True | False | True 

데이터 행 1 : ApplicationCode.InstrumentCodes {코드 1, Code4}

열 인덱스 또는 이름을 찾을 수있는 방법이 있습니까? 아니면이 문제를 해결할 다른 방법이 있습니까?

+1

ListView 바인딩을위한 XAML 코드는 무엇입니까? –

+0

안녕 마틴. 바인딩은 코드 뒤에 작성됩니다. AcnList.ItemsSource = repository.GetApplicationCodes(); GetApplicationCodes가 List를 반환합니다. Costin

답변

0

내가 지금까지 가지고이 솔루션은 동적으로 열을 추가하고 모든 컬럼에 ConverterParameter를 설정하는 것입니다.

foreach (var instrument in instruments) 
{ 
    var column = new GridViewColumn 
         { 
          HeaderTemplate = GetColumnHeaderTemplate(instrument), 
          CellTemplate = GetColumnCellTemplate(instrument), 
          Header = instrument, 
         }; 

    view.Columns.Add(column); 
} 

private static DataTemplate GetColumnCellTemplate(string instrument) 
{ 
    var binding = new Binding 
    { 
     ConverterParameter = instrument, 
     Converter = new InstrumentSelectionConverter(), 
     Mode = BindingMode.OneWay 
    }; 

    var template = new DataTemplate(); 
    template.VisualTree = new FrameworkElementFactory(typeof(CheckBox)); 
    template.VisualTree.SetBinding(ToggleButton.IsCheckedProperty, binding); 

    return template; 
} 

나는이 최선의 해결책이 아니다 알고 누군가가 나에게 .xaml에서 직접이 작업을 수행 할 수있는 방법을 보여줄 수 있다면 정말 감사하겠습니다.

1

열 이름은 시각적이어야합니다. 이는 필요한 데이터가 모두 기본 객체 모델에 있어야 함을 의미합니다. 따라서 데이터의 각 행은 하나의 객체입니다.

아마 코드의 재구성으로도 변환기의 필요성을 제거 할 수 있습니다 ...이 아이디어를 가로 지르는 예제이며 실제 사용을 위해 수정해야한다는 것을 명심하십시오.

internal class ApplicationCode 
    { 
     private CodeService _codeService = new CodeService(); 

     public int Code { get; set; } 
     public bool IsValidCode 
     { 
      get 
      { 
       return _codeService.DoesIntrumentCodeExist(Code.ToString()); 
      } 
     } 
    } 

    internal class CodeService 
    { 
     private IEnumerable<string> _instrumentCodes; 

     public CodeService() 
     { 
      //instantiate this in another way perhaps via DI.... 
      _instrumentCodes = new List<string>(); 
     } 

     public bool DoesIntrumentCodeExist(String instrumentCode) 
     { 
      foreach (String code in _instrumentCodes) 
      { 
       if (code == instrumentCode) 
        return true; 
      } 

      return false; 
     } 
    } 
+0

안녕하십니까, 데이터가 UI 표현이 아니라 객체 모델에 있어야한다는 것에 전적으로 동의합니다. 모델에 열 이름의 모든 코드를 포함 할 수는 있지만 문제가 여전히 존재하여 열 인덱스를 모르므로 해당 코드를 확인할 수 있습니다. – Costin

+0

@costin 위의 코드는 열 인덱스가 필요하지 않습니다 ... IEnumerable 내에 true/false를 반환하는 CodeService를 호출하는 새 ApplicationCode 개체 내의 데이터를 푸시하는 것입니다.

+0

안녕하세요 @Aaron 및 답변 감사합니다. 아직도 이해할 수없는 것이 있습니다 :). 한 행에 하나의 ApplicationCode 개체가 있습니다. 모든 행에서 2에서 8-9 열 사이를 동적으로 가질 수 있습니다. (또한 설명에 대한 명확한 설명이없는 경우 질문에 작은 예제를 추가했습니다.) 내가보기에 문제는 메서드의 매개 변수로 설정된 코드 때문에 DoesInstrumentExists 메서드가 모든 열에 대해 정확히 동일하게 호출된다는 것입니다. 모든 열에 대해 동일합니다. – Costin