多数のソリューション提案を確認した後でも、xaml で単純な双方向バインディングを機能させることができません。Window、dataContext、および App があります。問題は次のとおりです。
a) App コンストラクターの実行中に、ウィンドウ (.Show
同じコンストラクターで初期化および -ed) が表示されますが、C# コードでチェックボックスの値を数回切り替えても、まったく更新されません。
b) App コンストラクターが終了すると、Window は 1 回だけ更新されます。Window のチェックボックスをクリックすると、App のイベント ハンドラー (DataContext プロパティの変更通知にバインドされている) が、表示される文字列のリストのサイズを大きくするように設定しました。リストの増加はコードでは正しく行われますが、ウィンドウには反映されません。
まとめ:
- ウィンドウでのユーザー入力は、アプリの C# コードに問題なく到達します。チェック ボックスの変更などに対応できます。
- 反対方向は機能しません。アイテムがコードによって dataContext で変更されるたびに、iNotifyProperty が実装および実行されていても、ウィンドウは自動的に更新されません。
私が期待することは次のとおりです。
a) App コンストラクターが実行され、CheckBox 値が切り替えられている間、ウィンドウはボックスのチェックを設定/クリアすることで変更を反映する必要があります。
b) App コンストラクターが終了した後、CheckBox を FALSE から TRUE に切り替えるたびにNameList
、新しい文字列が追加されます。ウィンドウ内のリストがそれに応じて増加し、追加された完全なコンテンツが自動的に表示されることを期待していますNameList
。
観察:
- Window を呼び出す前に、Window の DataContext が設定されていることを確認し
InitializeComponent
ます。残念ながら本当に違いはありません... - MainWindow.xaml ファイルの VS で 1 つの手がかりを取得します。CheckBox パスと ListBox Binding
NameList
に注釈が付けられてCannot resolve symbol due to unknown DataContext
います。 . これは、ランタイムバインディングが実際に機能するはずであることを示しています...明らかに一方向のみで、双方向ではありません。
MainWindow.xaml:
<Window x:Class="StatisticsEvaluation.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>
<StackPanel Orientation="Vertical">
<CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="CheckBox" />
<ListBox ItemsSource="{Binding NameList, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock FontSize="18" FontFamily="Arial" Foreground="Black" Text="TextBlock" Visibility="Visible" />
</StackPanel>
</Grid>
MainWindow.xaml.cs:
namespace StatisticsEvaluation
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
}
}
}
アプリと DataContext:
namespace StatisticsEvaluation
{
public class DataContextClass : INotifyPropertyChanged
{
private bool isChecked;
public bool IsChecked
{
get
{
return isChecked;
}
set
{
isChecked = value;
OnPropertyChanged("IsChecked");
}
}
private List<string> nameList;
public List<string> NameList
{
get
{
return nameList;
}
set
{
nameList = value;
OnPropertyChanged("NameList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private MainWindow MyWindow { get; set; }
private DataContextClass MyDataContext{ get; set; }
private void HandleDataContextPropertyChange(object sender, PropertyChangedEventArgs e)
{
// If the CheckBox was just toggled to TRUE, increase the NameList
// with an additional name and call OnPropertyChanged on it ...
// hoping that this would trigger a Window UI update - but no luck !
if ((e.PropertyName == "IsChecked") && MyDataContext.IsChecked)
{
var randomProvider = new Random();
MyDataContext.NameList.Add(randomProvider.Next().ToString());
MyDataContext.OnPropertyChanged("NameList");
}
}
public App()
{
MyDataContext = new DataContextClass();
MyDataContext.PropertyChanged += HandleDataContextPropertyChange;
MyWindow = new MainWindow {DataContext = MyDataContext};
MyWindow.InitializeComponent();
MyWindow.Show();
MyDataContext.NameList = new List<string>();
MyDataContext.NameList.Add("FirstName");
MyDataContext.NameList.Add("SecondName");
MyDataContext.NameList.Add("ThirdName");
MyDataContext.IsChecked = true;
Thread.Sleep(3000);
MyDataContext.IsChecked = false;
Thread.Sleep(3000);
MyDataContext.IsChecked = true;
}
}
}
アプリを起動すると、アプリ コンストラクターがヒットすると、次のウィンドウが表示されます.Show
。
App コンストラクターが終了すると、 Window は 1 回更新されますが、その後は に追加される文字列の数に関係なく、二度と更新されませんNameList
。
任意のアイデア、なぜ私の双方向バインディングは一方向にしか機能しないのですか?