0

私はWPFを初めて使用するので、これが明らかな質問である場合は、お詫び申し上げます。XAMLに簡単なチェックボックスがあります。

<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" 
ItemsSource="{Binding Selections}" >
    <ListBox.ItemTemplate>
            <DataTemplate>
                    <Grid >
                    <CheckBox IsChecked="{Binding IsChecked}" 
                       Content="{Binding Path=Item.SelectionName}" />
                    </Grid >  
            </DataTemplate>
        </ListBox.ItemTemplate>
</ListBox>

バインディングとINotifyPropertyChangedを許可するための簡略化されたコードビハインドは次のとおりです。

public ObservableCollection<CheckedListItem<Selection>> Selections { get; set; }

public class Selection
{
    public String SelectionName { get; set; }
}

  Selections = new ObservableCollection<CheckedListItem<Selection>>();
  Selections.Add(new CheckedListItem<Selection>(new Selection() 
         { SelectionName = "SomeName" }, isChecked: true));

    public class CheckedListItem<T> : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private bool isChecked;
        private T item;

        public CheckedListItem()
        { }

        public CheckedListItem(T item, bool isChecked = false)
        {
            this.item = item;
            this.isChecked = isChecked;
        }

        public T Item
        {
            get { return item; }
            set
            {
                item = value;
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
            }
        }


        public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                isChecked = value;
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
            }
        }
    }

次に、各チェックボックスに関連付けられたテキストボックスを追加する必要があるため、XAMLでは次のようになります。

    <ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" 
           ItemsSource="{Binding Selections}" Margin="12,22,12,94">
    <ListBox.ItemTemplate>
            <DataTemplate>
                    <Grid >
                    <CheckBox IsChecked="{Binding IsChecked}" 
                       Content="{Binding Path=Item.SelectionName}" />
                    <<TextBox />
                    </Grid >  
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

これをObservableCollectionの一部として含め、CheckBoxと関連するTextBoxの両方にバインディングを設定する方法に少し困惑していますか?両方を使用して一緒に追加されSelections.Add(new CheckedListItem<Selection>(new Selection() { SelectionName = "SomeName" }, isChecked: true));ているため、混乱が生じています。

編集:完全なコードを追加しました

public partial class SelectionSettingWindow : Window
    {

        public ObservableCollection<CheckedListItem<Selection>> Selections { get; set; }

        public class Selection
        {
            public String SelectionName { get; set; }
            public string SelectionTextField { get; set; }
        }

        public SelectionSettingWindow()
        {
            InitializeComponent();

            Selections = new ObservableCollection<CheckedListItem<Selection>>();
            string fg = @"Item1,true,TExtbox1text:Item2,true,TExtbox2text:Item3,false,TExtbox3text"; //Test String
            string[] splitSelections = fg.Split(':');
            foreach (string item in splitSelections)
            {
                string[] spSelectionSetting = item.Split(',');

                bool bchecked = bool.Parse(spSelectionSetting[1].ToString());
                string tbText = spSelectionSetting[2].ToString();
                Selections.Add(new CheckedListItem<Selection>(new Selection() 
                   { SelectionName = spSelectionSetting[0].ToString(),   
                       SelectionTextField = bText }, isChecked: bchecked));

            }

            DataContext = this;
        }

        public class CheckedListItem<T> : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            private bool isChecked;
            private T item;
            private string textField;

            public CheckedListItem()
            { }

            public CheckedListItem(T item, bool isChecked = false)
            {
                this.item = item;
                this.isChecked = isChecked;
            }

            public T Item
            {
                get { return item; }
                set
                {
                    item = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
                }
            }


            public bool IsChecked
            {
                get { return isChecked; }
                set
                {
                    isChecked = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
                }
            }

            public string TextField
            {
                get { return textField; }
                set
                {
                    textField = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("TextField"));
                }
            }
        }
}
4

1 に答える 1

2
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" 
       ItemsSource="{Binding Selections}" Margin="12,22,12,94">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" 
                   Content="{Binding Path=Item.SelectionName}" />
                <TextBox Text="{Binding Item.SelectionTextField, Mode=TwoWay}" />
            </StackPanel>  
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

SelectionTextField上記を、クラスのテキストボックスを使用して編集する必要のあるフィールドに置き換えますSelection

<Grid>をに変更して、<StackPanel>それらが互いに重なって表示されないようにし、バインディングをTwoWayに変更して、変更がモデルに反映されるようにしたことに注意してください。

Selectionクラスが実装されていることを確認しますINotifyPropertyChanged(ObservableCollectionは、コレクションに追加またはコレクションから削除されたときにUIを更新します。コンテンツのプロパティが変更されたときに通知することについては何も知らないため、独自に行う必要があります)

INotifyPropertyChanged多くのクラスに実装するのは面倒です。これには、基本クラスの実装が役立つと思います。これに加えて、レイズプロパティの追加のリフレクションヘルパーがここで利用可能になり、スニペットが利用可能になりました。これはSilverlightですが、WPFでは正常に機能するはずです。ダウンロードで提供したコードを使用するproprpcと、タブを入力して押すだけで、VisualStudioが変更を通知するプロパティをスタブします。ここにある私の古いブログ投稿の1つにいくつかの説明があり、コードとスニペットのベースとなった場所が評価されています。

于 2012-10-09T22:05:25.393 に答える