2011-01-11 4 views
2

Я новичок в WPF, и у меня есть некоторые трудности, когда я пытаюсь заполнить ListView списком пользовательских объектов.Проблема с привязкой WPF

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

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

У меня есть список ApplicationCode, который я установил в ItemsSource в ListView. Мне нужно отобразить 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 {code1, code4}

Существует способ, чтобы выяснить, индекс столбца или имя? Или есть другой способ решить эту проблему?

+1

Каков ваш код XAML для привязки ListView? –

+0

Привет, Мартин. Связывание выполняется в коде позади: AcnList.ItemsSource = repository.GetApplicationCodes(); GetApplicationCodes возвращает список 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

Привет, Я полностью согласен с вами в том, что данные должны быть в объектной модели, а не в представлении пользовательского интерфейса. Я мог бы включить все коды (из имен столбцов) в модель, но проблема все еще существует, что я не знаю индекса столбца, поэтому я мог проверить соответствующий код. – Costin

+0

@costin Приведенный выше код не нуждается в индексе столбца ... он касается нажатия данных в новом объекте ApplicationCode, который вызывает вызов CodeService, который вернет true/false, если он существует в IEnumerable

+0

Привет @Aaron и Спасибо за твой ответ. Я еще что-то не понимаю :). У меня есть один объект ApplicationCode для каждой строки. В каждой строке я могу динамически от 2 до 8-9 столбцов. (Я также добавил небольшой пример в вопросе, если описание не очень ясное.) Проблема, которую я вижу, заключается в том, что метод DoInstrumentExists вызывается точно так же для каждого столбца, поскольку код, заданный как параметр для метода , одинаково для каждого столбца. – Costin

Смежные вопросы