0

本でWPFのバインディングを学びます。私はそのようなコードを書きました:

using System;

namespace WpfBinding {
    enum SomeColors {
        Red,
        Green,
        Blue,
        Gray
    }
}

using System;

namespace WpfBinding {
    class TestItem {
        SomeColors color;

        public TestItem(SomeColors color) {
            Color = color;
        }
        internal SomeColors Color {
            get { return color; }
            set { color = value; }
        }
        public override string ToString() {
            return Color.ToString();
        }
    }
}

私のウィンドウの XAML:

<Window x:Class="WpfBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox x:Name="listBox" HorizontalAlignment="Stretch" 
                 VerticalAlignment="Stretch" Margin="5"/>
        <ComboBox x:Name="comboBox" HorizontalAlignment="Stretch" 
                  VerticalAlignment="Top" Margin="5" Grid.Column="1"/>
    </Grid>
</Window>

コードを使用してバインディングを作成しようとしました:

using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfBinding {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            // Data for listbox
            TestItem[] items = new TestItem[] {
                new TestItem(SomeColors.Red), 
                new TestItem(SomeColors.Green), 
                new TestItem(SomeColors.Green), 
                new TestItem(SomeColors.Red), 
                new TestItem(SomeColors.Blue), 
                new TestItem(SomeColors.Red), 
            };
            // Create ObservableCollection item
            ObservableCollection<TestItem> collection = new ObservableCollection<TestItem>(items);
            listBox.ItemsSource = collection;// set data for listbox

            comboBox.ItemsSource = Enum.GetValues(typeof(SomeColors)); // Get items from my enum

            // Create bindings
            Binding bind = new Binding();
            bind.Source = listBox;
            bind.Path = new PropertyPath("SelectedItem.Color");
            bind.Mode = BindingMode.TwoWay;
           comboBox.SetBinding(ComboBox.SelectedItemProperty, bind);
        }
    }
}

しかし、私のバインディングは機能していません。なんで?

画面: ここに画像の説明を入力

4

4 に答える 4

2

デバッグするときは、VisualStudioの出力ウィンドウを確認すると常に便利です。あなたがそこを見ていたら、あなたはこれを見たでしょう:

System.Windows.Data Error: 40 : BindingExpression path error: 'Color' property not found on 'object' ''TestItem' (HashCode=20856310)'. BindingExpression:Path=SelectedItem.Color; DataItem='ListBox' (Name='listBox'); target element is 'ComboBox' (Name='comboBox'); target property is 'SelectedItem' (type 'Object')

正確には、バインディングはパブリックプロパティでのみ実行できるため、

internal SomeColors Color

する必要があります

public SomeColors Color
于 2012-11-15T19:21:54.407 に答える
2

ここにエラーがあります -

System.Windows.Data Error: 40 : BindingExpression path error: 'Color' property
not found on 'object' ''TestItem' (HashCode=13974362)'.  
BindingExpression:Path=SelectedItem.Color; DataItem='ListBox' (Name='listBox');
target element is 'ComboBox' (Name='comboBox'); target property is 'SelectedItem'
(type 'Object')

Color publicの代わりにプロパティを作成する必要がありますinternal

ここのMSDNから-

バインディングのバインディング ソース プロパティとして使用するプロパティは、クラスのパブリック プロパティである必要があります。明示的に定義されたインターフェイス プロパティには、バインディングの目的でアクセスすることはできません。また、基本実装を持たない保護されたプライベート プロパティ、内部プロパティ、または仮想プロパティにもアクセスできません。

于 2012-11-15T19:26:38.837 に答える
2

問題は、クラスが実装していないことだと思いますINotifyPropertyChanged

プロパティの値がいつ変更されたかをバインディングが知るた​​めには、通知を送信する必要がありますINotifyPropertyChanged

アップデート

したがって、リストボックスはObservableCollection、変更通知を提供する にバインドされますが、リスト ボックスにのみ、コレクションにアイテムを追加または削除する場合にのみバインドされます。

ビジュアル スタジオ ( http://msdn.microsoft.com/en-us/library/dd409960%28v=vs.100%29.aspx ) でWPF バインディング トレース情報を有効にすることもできます。も進んでいます。

最後に気付いたのは、TestItemクラスの Color プロパティが としてマークされていることinternalです。でない限り、WPF はそのプロパティにアクセスできませんpublic

于 2012-11-15T19:07:26.403 に答える
1

皆さんありがとう。コードを編集しました:

using System;
using System.ComponentModel;

namespace WpfBinding {
    public class TestItem : INotifyPropertyChanged{
        SomeColors color;

        public TestItem(SomeColors color) {
            Color = color;
        }
        public SomeColors Color {
            get { return color; }
            set { color = value;
            OnPropertyChanged("Color");
                 }
        }
        public override string ToString() {
            return Color.ToString();
        }

        void OnPropertyChanged(String name) {
            PropertyChangedEventHandler temp = PropertyChanged;
            if (null != temp) {
                temp(this, new PropertyChangedEventArgs(name));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfBinding {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            // Data for listbox
            TestItem[] items = new TestItem[] {
                new TestItem(SomeColors.Red), 
                new TestItem(SomeColors.Green), 
                new TestItem(SomeColors.Green), 
                new TestItem(SomeColors.Red), 
                new TestItem(SomeColors.Blue), 
                new TestItem(SomeColors.Red), 
            };
            // Create ObservableCollection item
            ObservableCollection<TestItem> collection = new ObservableCollection<TestItem>(items);
            listBox.ItemsSource = collection;// set data for listbox

            ObservableCollection<SomeColors> collection2 = new 
                ObservableCollection<SomeColors>(Enum.GetValues(typeof(SomeColors)).Cast<SomeColors>());
            comboBox.ItemsSource = collection2; // Get items from my enum
            // Create bindings
            Binding bind = new Binding();
            bind.Source = listBox;
            bind.Path = new PropertyPath("SelectedItem.Color");
            bind.Mode = BindingMode.TwoWay;
           comboBox.SetBinding(ComboBox.SelectedItemProperty, bind);
        }
    }
}

スクリーンを見てください: ここに画像の説明を入力

于 2012-11-15T19:42:27.980 に答える