2011-01-11 27 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コレクションに含まれているかどうかに応じてチェック/チェック解除できるチェックボックスを残りの列に対して表示する必要があります。

私はデータバインディングでコンバータを使用する]チェックボックスを設定するために:私はバインディングとIセルデータの時点で現在の列であるかを知ることができないので、私が持っている問題がある

<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

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上記のコードはカラムインデックスを必要としません...新しいApplicationCodeオブジェクト内のデータをプッシュして、CodeServiceを呼び出します。これはIEnumerable内にtrue/falseを返します。

+0

こんにちは@Aaronと答えてくれてありがとう。まだ理解できないものがあります:)。行ごとに1つのApplicationCodeオブジェクトがあります。すべての行で、2〜8〜9の列を動的に持つことができます。 (私はまた、もしその説明があまり明確でない場合には、小さな例を追加しました。) 私が見ている問題は、メソッドのパラメータとしてコードが設定されているため、メソッドDoesInstrumentExistsはすべての列に対して正確に同じですすべての列で同じです。 – Costin

関連する問題