ListBox
エキスパンダーを含む ItemTemplateを含むダイアログ ウィンドウがあります。これIsExpanded
は、アイテム ビュー モデルのプロパティにバインドされています。のプロパティは、アイテム ビュー モデル オブジェクトのプロパティにListBoxItem
もIsSelected
バインドされます。IsExpanded
最後に、 のSelectedItem
プロパティはListBox
、ビュー モデル内の同じ名前のプロパティにバインドされます。
ここでの問題は、ダイアログを表示する前にビューモデルを設定し、それをDataContext
ダイアログのエキスパンダーの表示はありません。
ダイアログを表示した後にビューモデルを設定すると、たとえば. ダイアログの Loaded ハンドラーでは、期待どおりに機能します。ここで何が起こっているのか、それを修正する最善の方法は何ですか?
ダイアログ ウィンドウは次のように定義されます。
<Window x:Class="WpfApplication1.Dialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication1"
Title="Dialog" Height="300" Width="300">
<Grid>
<ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<Expander Header="Expander" x:Name="MyExpander" IsExpanded="{Binding IsExpanded, Mode=TwoWay}">
<Rectangle Width="100" Height="20" Fill="Red" />
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsExpanded, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
そしてViewModel(簡潔にするために実装は含まれていません):
public interface IMyViewModel : INotifyPropertyChanged
{
object SelectedItem { get; set; }
ObservableCollection<IMyItemViewModel> Items { get; }
}
public interface IMyItemViewModel : INotifyPropertyChanged
{
bool IsExpanded { get; set; }
}
次に、ボタンのある単純なメイン ウィンドウがあり、そのClick
ハンドラーは次のように定義されます。
private void Button_Click(object sender, RoutedEventArgs e)
{
MyViewModel vm = new MyViewModel();
MyItemViewModel item = new MyItemViewModel();
vm.Items.Add(item);
vm.SelectedItem = item;
Dialog dialog = new Dialog();
dialog.DataContext = vm;
dialog.ShowDialog();
}
アプリケーションを実行してボタンをクリックすると、ダイアログが表示され、展開矢印は展開状態であることを示しますが、その内容は表示されません。エキスパンダーをクリックすると折りたたまれ、もう一度クリックすると展開され、今度はコンテンツが表示されます。ただし、ダイアログの代わりにメインウィンドウに同じコードを直接配置すると、想定どおりに機能します。
直接設定する代わりにa を実行すると、うまくいくDispatcher.BeginInvoke(new Action(() => vm.SelectedItem = item);
ように見えますが、これは少し不安定に感じます。
この問題を解決するにはどうすればよいですか?