2009-07-10 11 views
1

OK、...広すぎる質問には申し訳ありませんが、のは、あなたたちはお勧めか見てみましょう WPFのListViewコントロールのために

私はXMLファイルによってロードされたWPFのListViewのは、使用しているのXAMLでのいくつかの項目を無効にする方法XAML(下のコード)

私はリストビューにあるものと一致する項目を持つ2番目のXMLファイルを持っています。しかし、で、2番目のファイルに一致する場合は、そのListItemを無効にします。

簡単な例:

私のListViewがそれであります

    Joe 
        Fred 
        Jim 

(それが最初のXMLファイルをロードしたため)

私の2番目のXMLファイルは、(基本的に)があります。

    Joe 
        Jim 

リストビューで何とかこの2番目のファイルを消費したい"Fred"は無効になっています。

私は、XAMLのどこかに適用する、ある種の「フィルタ」であると仮定しています。

<ListView Name="lvwSourceFiles" 
      Margin="11,93,0,12" VerticalContentAlignment="Center" 
      HorizontalAlignment="Left" Width="306" 
      Cursor="Hand" TabIndex="6" 
      ItemsSource="{Binding}" 
      SelectionMode="Multiple" 
      SelectionChanged="lvwSourceFiles_SelectionChanged" > 
    <ListBox.DataContext> 
     <XmlDataProvider x:Name="xmlSourceFiles" XPath="AssemblyUpdaterSource/sources/source/File" /> 
    </ListBox.DataContext> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="{x:Type ListViewItem}"> 
      <EventSetter Event="PreviewMouseRightButtonDown" 
         Handler="OnSourceListViewItemPreviewMouseRightButtonDown" /> 
     </Style> 
    </ListView.ItemContainerStyle> 
</ListView> 

答えて

5

これはかなり複雑な作業なので、XAMLではなくコードで行うことをお勧めします。これをコードビハインドで完全に行う場合は、ListView.Loadedイベントのハンドラを追加してから、アイテムを追加したり、そこで特定のアイテムを無効にしたりするすべてのロジックを実行できます。確かに、ListViewはデータにバインドされませんが、このような特殊なケースでは、バインディングなしでより良いかもしれません。

はしかし、これはXAMLで行われ、マークアップあなたに似たを使用してできることを示すために、私は次の例を構築しました。私の例では、XmlDataProviderではなくListを使用していますが、要点はまったく同じです。リストを構築するコードをXMLをロードするコードに置き換えるだけで済みます。ここで

は私のコードビハインドファイルです:

public partial class Window2 : Window 
{ 
    private List<Person> _persons = new List<Person>(); 

    public Window2() 
    { 
     InitializeComponent(); 

     _persons.Add(new Person("Joe")); 
     _persons.Add(new Person("Fred")); 
     _persons.Add(new Person("Jim")); 
    } 

    public List<Person> Persons 
    { 
     get { return _persons; } 
    } 

    public static List<Person> FilterList 
    { 
     get 
     { 
      return new List<Person>() 
      { 
       new Person("Joe"), 
       new Person("Jim") 
      }; 
     } 
    } 
} 

public class Person 
{ 
    string _name; 

    public Person(string name) 
    { 
     _name = name; 
    } 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    public override string ToString() 
    { 
     return _name; 
    } 
} 

これは単にカップルのリストを定義し、名前文字列を保持しているクラス定義、。

次に、私のXAMLマークアップ:ここ

<Window x:Class="TestWpfApplication.Window2" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:TestWpfApplication" 
xmlns:sys="clr-namespace:System;assembly=mscorlib" 
Title="Window2" Height="300" Width="300" 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
<Window.Resources> 
    <local:PersonInListConverter x:Key="personInListConverter"/> 
    <ObjectDataProvider x:Key="filterList" ObjectInstance="{x:Static local:Window2.FilterList}"/> 
</Window.Resources> 
<StackPanel> 
    <ListView ItemsSource="{Binding Persons}" 
       SelectionMode="Multiple" 
       Name="lvwSourceFiles" Cursor="Hand" VerticalContentAlignment="Center"> 
     <ListView.ItemContainerStyle> 
      <Style TargetType="{x:Type ListViewItem}"> 
       <Setter Property="IsEnabled" 
         Value="{Binding Name, Converter={StaticResource personInListConverter}, ConverterParameter={StaticResource filterList}}"/> 
      </Style> 
     </ListView.ItemContainerStyle> 
    </ListView> 
</StackPanel> 

私は、現在の人の名前プロパティにそれぞれのListViewItemのIsEnabledプロパティをバインドします。その人の名前がリストにあるかどうかを確認するコンバータを提供します。 ConverterParameterは、2番目のXMLファイルに相当するFilterListを指しています。

public class PersonInListConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     string name = (string)value; 
     List<Person> persons = (parameter as ObjectDataProvider).ObjectInstance as List<Person>; 

     return persons.Exists(person => name.Equals(person.Name)); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

そして最終結果:

alt text

3

私の解決方法はそれほど単純ではないので、リスト内の項目のdataTemplateを作成する必要があります。 データテンプレートにはデータトリガーが必要です。つまり、アイテムが他のXMLファイルに存在するかどうかを示す、ある種のプロパティをアイテムソース内に持つ必要があります。

はそう私が言うことをしようとしていることは、uはコードからXMLファイルを読み込み、名前の小道具が含まれているし、プロパティが存在し、他のファイルに結合する独自のカスタムクラスを生成する必要があること

です私は答えを書いていた誘い込む考え

別の解決策は、名前を取得し、他のファイルをチェックし、ブール値を返しますコンバータにアイテムのでIsEnabledプロパティをバインドすることです。

+0

@Chenあなたがそのようなコンバータにバインドする方法の例を与えることができる最後に、ここでのコンバータはありますか? – KevinDeus

+0

必ずしもそうではありません。このためにDataTemplateを使用する必要はありません。コンバーターとのバインディングはItemContainerStyleで行うことができます。 – Charlie