-1

ListView各項目が読み取り専用 (つまり、選択のみ、 no TextBox)で表示される場所を定義しましたComboBox( に従ってItemTemplate)。

これらの各コンボ ボックスから選択できるアイテムの特定のリストがあります。ただし、一度に 2 つのコンボ ボックスで項目を選択することはできません。これを確実にするために、アイテムがコンボ ボックスの 1 つで選択されたら、他のすべてのコンボ ボックス (選択されているものを除く) から削除する必要があり、選択が解除されたら追加する必要があります。他のすべてのコンボボックスに再び。

ああ、もう 1 つ: 表示される項目の順序は、完全なリストと比較して変更してはなりません。

私の質問は次のとおりです。どうすればこの動作を実現できますか?

私は頭に浮かんだ3つの可能な解決策を試しました:

  • 既存のアイテムの完全なリストと、外界へのバインディングを介して除外された (使用された) アイテムのリスト、および選択されたアイテムのプロパティを取得する新しいヘルパー コントロール クラスを作成しました。そのコントロール クラスをItemTemplate;に含めることができます。そのテンプレート内のコンボ ボックスは、そのItemsSourceプロパティを、ItemsProvider既存のアイテムのリスト、除外されたアイテムのリスト、および選択されたアイテムを結び付けるヘルパー クラスのプロパティにバインドし、その特定のコンボのアイテムの単一の列挙を返します。箱。
    ただし、リストの変更に関するすべての更新通知でどういうわけか迷子になりました。のすべての組み合わせに個別に対応する必要があるのではないかと心配しています。NotifyCollectionChangedAction2 つの入力リストのうち、多数の更新メソッドが存在する可能性があるため、これは正しい方法ではないと思いました。
  • 既存のアイテムのリストを、各アイテムとともにブール値を格納するリストに変更したので、各アイテムに非表示または非表示のフラグを付けることができました。これにより、アイテムの順序を維持しながら除外アイテムのリストを作成する必要がなくなり、前述の組み合わせた変更通知の複雑さが軽減されます。残念ながら、リスト自体はそのソリューションで変更されないため、依存関係プロパティ インフラストラクチャにヘルパー クラス
    のプロパティを通知させる方法がわかりません。ItemsSource
  • バインディング方法で WPF使用する必要はありません。ここでも分離コードを実行できます。そこで、すべての を反復処理しListViewItem、それぞれのコンボ ボックスを取得して、項目リストを手動で更新しようとしました。ListViewItemしかし、アイテム テンプレートが読み込まれた後、にアクセスする適切なタイミングが見つかりませんでした。そのような状況にはイベントがないようで、ListView.ItemContainerGenerator読み取り専用であるため、封印ItemContainerGeneratorされたクラスでなくても、オーバーライドできるカスタム リスト ビュー項目を作成する独自の特殊化を割り当てることができませんでした。ItemContainerGeneratorOnApplyTemplate
4

2 に答える 2

0

Lists を ViewModel の別の Lists にバインドし、選択した項目をバインドしてそれらの Lists を変更するメソッドをトリガーすると、結果を取得できます。以下と同様です。

MainWindow.xaml の Xaml:

<Window x:Class="ComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="180" />
            <ColumnDefinition Width="180" />
            <ColumnDefinition Width="180" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="26" />
        </Grid.RowDefinitions>
        <ComboBox Name="cboOne" Grid.Column="0" Grid.Row="0" ItemsSource="{Binding CboOneList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding CboOneValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
        <ComboBox Name="cboTwo" Grid.Column="1" Grid.Row="0" ItemsSource="{Binding CboTwoList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding CboTwoValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
        <ComboBox Name="cboThree" Grid.Column="2" Grid.Row="0" ItemsSource="{Binding CboThreeList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding CboThreeValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
    </Grid>
</Window>

MainWindow.xaml の分離コード:

using System.Windows;
using System.Windows.Controls;

namespace ComboBox {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();

        this.DataContext = new ComboBoxViewModel();

    }

    private void cboOne_SelectionChanged(object sender, SelectionChangedEventArgs e) {

    }
}
}

ビューモデル:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.ComponentModel;

 namespace ComboBox {
class ComboBoxViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    List<string> master = new List<string>() { "A", "B", "C", "D", "E", "F" };

    #region C'tor
    public ComboBoxViewModel() {
        RetrieveLists();
    }
    #endregion

    #region Methods
    protected void OnPropertyChanged(String propertyName) {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if(null != handler) {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public void RetrieveLists() {
        List<string> tempOne = (from a in master
                                where !a.Equals(CboTwoValue) && !a.Equals(CboThreeValue)
                                select a).ToList();
        CboOneList = tempOne;

        List<string> tempTwo = (from a in master
                                where !a.Equals(CboOneValue) && !a.Equals(CboThreeValue)
                                select a).ToList();
        CboTwoList = tempTwo;

        List<string> tempThree = (from a in master
                                where !a.Equals(CboTwoValue) && !a.Equals(CboOneValue)
                                select a).ToList();
        CboThreeList = tempThree;
    }
    #endregion

    #region Properties
    private string cboOneValue = string.Empty;
    public string CboOneValue {
        get {
            return cboOneValue;
        }
        set {
            if(!value.Equals(cboOneValue)) {
                cboOneValue = value;
                RetrieveLists();
                OnPropertyChanged("CboOneValue");
            }
        }
    }
    private string cboTwoValue = string.Empty;
    public string CboTwoValue {
        get {
            return cboTwoValue;
        }
        set {
            if(!value.Equals(cboTwoValue)) {
                cboTwoValue = value;
                RetrieveLists();
                OnPropertyChanged("CboTwoValue");
            }
        }
    }
    private string cboThreeValue = string.Empty;
    public string CboThreeValue {
        get {
            return cboThreeValue;
        }
        set {
            if(!value.Equals(cboThreeValue)) {
                cboThreeValue = value;
                RetrieveLists();
                OnPropertyChanged("CboThreeValue");
            }
        }
    }

    private List<string> cboOneList = new List<string>();
    public List<string> CboOneList {
        get {
            return cboOneList;
        }
        set {
            cboOneList = value;
            OnPropertyChanged("CboOneList");
        }
    }

    private List<string> cboTwoList = new List<string>();
    public List<string> CboTwoList {
        get {
            return cboTwoList;
        }
        set {
            cboTwoList = value;
            OnPropertyChanged("CboTwoList");
        }
    }

    private List<string> cboThreeList = new List<string>();
    public List<string> CboThreeList {
        get {
            return cboThreeList;
        }
        set {
            cboThreeList = value;
            OnPropertyChanged("CboThreeList");
        }
    }
    #endregion
}

}

于 2012-09-25T20:26:19.283 に答える