4

WPFには、ブール値のコレクションがありますか?値と私はこれらのそれぞれをプログラムで別々のチェックボックスにバインドしたいと思います。コード内のコレクション内の個々のアイテムの値を変更するとチェックボックスが更新され、その逆も同様になるように、バインディングをTwoWayにする必要があります。

私はこれを行う方法を理解しようと何年も費やしてきましたが、完全に行き詰まっています。次のコードでは、チェックボックスはウィンドウがロードされたときにのみ正しい値を取得します。それだけです。チェックボックスを変更しても、コレクションの値は更新されません。(更新:コレクションは同一の.NET3.5プロジェクトで更新されるため、これは.NET4のバグのようです。更新:Microsoftはバグを確認しており、.NET4リリースで修正される予定です。)

よろしくお願いします!

C#:

namespace MyNamespace
{
    public partial class MyWindow : Window, INotifyPropertyChanged
    {
        public MyWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
               PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }

        public List<bool?> myCollection = new List<bool?>
            { true, false, true, false, true, false };

        public List<bool?> MyCollection
        {
            get { return myCollection; }
            set { myCollection = value; }
        }
    }
}

XAML:

<CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}">
4

3 に答える 3

5

これを機能させるには、ここで変更する必要があることがいくつかあります。まず、探している変更通知を取得するために、INotifyPropertyChangedインターフェイスを実装するオブジェクトでブール値をラップする必要があります。現在、インターフェイスを実装していないコレクション内のブール値にバインドしています。これを行うには、次のようなラッパークラスを作成できます。

  public class Wrapper: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private bool val = false;

        public bool Val
        {
            get { return val; }
            set
            {
                val = value;
                this.OnPropertyChanged("Val");
            }
        }

        public Wrapper(bool val)
        {
            this.val = val;
        }

    }

次に、ブール値のリストではなく、フォームにこれらのオブジェクトを作成する必要があります。リストの代わりに監視可能なコレクションを使用して、追加および削除されたアイテムの通知が送信されるようにすることもできます。これを以下に示します。

public Window1()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private ObservableCollection<Wrapper> myCollection = new ObservableCollection<Wrapper>()
        {new Wrapper(true), new Wrapper(false), new Wrapper(true)};


    public ObservableCollection<Wrapper> MyCollection
    {
        get { return myCollection; }
    }

次に行うことは、UIのチェックボックスのリストを表示することです。これを行うために、WPFはitemscontrolsを提供します。ListBoxはitemscontrolであるため、これを開始点として使用できます。リストボックスのitemssourceをMyCollectionに設定します。次に、各Wrapperオブジェクトがリストボックスにどのように表示されるかを定義する必要があります。これは、Windowsリソースで作成されたデータテンプレートを使用して行うことができます。これを以下に示します。

<Window.Resources>
    <DataTemplate x:Key="myCollectionItems">
        <CheckBox IsChecked="{Binding Path=Val, Mode=TwoWay}"></CheckBox>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox ItemsSource="{Binding Path=MyCollection}" ItemTemplate="{StaticResource myCollectionItems}"></ListBox>
</Grid>

これにより、ブール値のリストにバインドされた値を持つチェックボックスの簡単なデモを実行できるようになります。

于 2010-01-17T20:42:28.660 に答える
0

何がうまくいかないと思いますか?それは私のために働いています:)

これが私のテストXAMLです:

<UniformGrid>
    <CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}"/>
    <ListBox ItemsSource="{Binding MyCollection}"/>
    <Button Content="Test" Click="Button_Click"/>
</UniformGrid>

これが私の背後にあるコードです:

private void Button_Click(object sender, RoutedEventArgs e)
{

}

(残りはあなたのものと同じです)

にブレークポイントを設定し、の値に従って更新されていることButton_Clickを確認しました。MyCollection[0]IsCheckedCheckBox

コレクションの種類をからList<bool?>に変更してみてください。ObservableCollection<bool?>おそらくそれが機能していないと思われる理由です(コレクションへの変更がビューの他の場所に反映されていないという事実)。

于 2010-01-17T20:35:11.933 に答える
0

に変更List<bool?>しますObservableCollection<bool?>。リストは、WPFがUIを更新する必要があるという変更通知を生成しません。ObservableCollectionはそうします。これは、リストエントリが変更され、それに応じてチェックボックスを更新する必要がある場合を処理します。

逆に言えば、List<bool?>-を使用しても機能します。つまり、チェックボックスを切り替えると、コレクションの値が変更されます。バインディング構文は確かに正しいです。

于 2010-01-17T20:36:12.693 に答える