私はWPFを初めて使用します。
文字列のコレクションをコンボボックスにバインドしようとしています。
_public ObservableCollection<string> ListString {get; set;}
_
バインディングとデータコンテキストは次のように設定されます
_<Window
x:Class="Assignment2.MainWindow"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:validators="clr-namespace:Assignment2"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}, Path=.}">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="109,103,0,0" Name="StringComboBox" VerticalAlignment="Top" Width="120" SelectionChanged="StringComboBox_SelectionChanged">
<ComboBox.ItemsSource>
<Binding Path="ListString" BindsDirectlyToSource="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"></Binding>
</ComboBox.ItemsSource>
</ComboBox>
_
コレクションが更新されているため、これが発生していることがわかりました。私が書いたら
_public MainWindow()
{
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
InitializeComponent();
}
_
動作しますが、次のように最初の行でInitializeComponent()
を上に移動すると、動作しません。
_ public MainWindow()
{
InitializeComponent();
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
}
_
私は何をすべきか??
問題を解決しました。 INotifyPropertyChangedを次のように実装しました
public partial class MainWindow : Window, INotifyPropertyChanged
アクセサを次のように変更しました
private ObservableCollection<string> listString;
public ObservableCollection<string> ListString
{
get
{
return listString;
}
set
{
listString = value;
NotifyPropertyChanged("ListString"); // method implemented below
}
}
次のイベントとイベントを発生させる方法を追加しました
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(name));
}
}
そしてそれは動作しますB)
コードをに変更するとどうなりますか
<Window
x:Class="Assignment2.MainWindow"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:validators="clr-namespace:Assignment2"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="109,103,0,0" Name="StringComboBox" VerticalAlignment="Top" Width="120" SelectionChanged="StringComboBox_SelectionChanged"
ItemsSource="{Binding ListString, Mode=OneWay}"/>
cs。
public MainWindow()
{
InitializeComponent();
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
this.DataContext=this;
}
ところで:mode = twowayでItemsSourceを設定することは私には意味がありません。コンボボックスがビューモデルの「新しいitemssourceを作成」することはありません。
編集:xamlでDataContextを設定しているため、最初のソリューションが機能すると思います。 InitializeComponent();を呼び出すと、DataContext = "{Binding RelativeSource = {RelativeSource Self}、Path =。}"が実行されると想定しています。また、ListStringプロパティは単なる自動プロパティであり、INotifyPropertyChangedを実装していないため、ctorが新しいListStringプロパティを作成したことはmainwindowviewに通知されません。
public ObservableCollection<string> ListString {get{return _list;}; set{_list=value; OnPropertyChanged("ListString");}}
両方のアプローチで機能するはずですが、MainWindowクラスにINotifyPropertyChangedを実装する必要があります。
私には、問題は「更新」ListString
であったようです。それをプロパティ(選択された答え)にすることは、それを回避する1つの方法です。あるいは、インスタンス化をインライン化するか、InitializeComponent
の前に配置しても大丈夫だと思います。
頻繁に更新が行われることが予想される場合は、ObservableCollection
をマネージャークラスにカプセル化すると役立つ場合があります。このような設定で自分の問題をトラブルシューティングした後、この質問を見つけました。 INotifyCollectionChanged
を実装し、そのようにイベントを転送することで機能しました
/// <summary>
/// Maintains an observable (i.e. good for binding) collection of resources that can be indexed by name or alias
/// </summary>
/// <typeparam name="RT">Resource Type: the type of resource associated with this collection</typeparam>
public class ResourceCollection<RT> : IEnumerable, INotifyCollectionChanged
where RT : class, IResource, new()
{
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add { Ports.CollectionChanged += value; }
remove { Ports.CollectionChanged -= value; }
}
public IEnumerator GetEnumerator() { return Ports.GetEnumerator(); }
private ObservableCollection<RT> Ports { get; set; }
private Dictionary<string, RT> ByAlias { get; set; }
private Dictionary<string, RT> ByName { get; set; }
}
コードビハインドでコンボボックスのアイテムソースを設定するか、リストにデータが入力された後にデータコンテキストを再度設定するか、inotifychangedを使用してプロパティの変更を行うことができます。
public MainWindow()
{
InitializeComponent();
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
StringComboBox.ItemsSource = ListString;
}