wpf - 第一次从绑定(bind)扩展时,ListBox 内的扩展器不显示内容

标签 wpf c#-4.0 data-binding

我有一个对话框窗口,其中包含一个 ListBox,其 ItemTemplate 包含一个扩展器。 它的 IsExpanded 绑定(bind)到项目 View 模型中的一个属性。 ListBoxItemIsSelected 属性还绑定(bind)到项目 View 模型对象中的 IsExpanded 属性。最后,ListBoxSelectedItem 属性绑定(bind)到 View 模型中同名的属性。

这里的问题是,在显示对话框之前设置 View 模型并将其设置到对话框的 DataContext 时,列表框中的项目将按其应有的方式被选中,展开器箭头显示处于展开状态,但未显示展开器的内容。

如果我在显示对话框之后设置 View 模型,例如。在对话框的 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();
}

当我运行应用程序并单击按钮时,会出现对话框,展开器箭头指示它处于展开状态,但其内容未显示。单击展开器将其折叠,再次单击将其展开,这次显示内容。 然而,将相同的代码直接放在主窗口而不是对话框中可以按预期工作。

如果我只是执行 Dispatcher.BeginInvoke(new Action(() => vm.SelectedItem = item); 而不是直接设置它,事情似乎也可以工作,但这感觉有点不稳定.

如何解决这个问题?

最佳答案

听起来,如果 IsExpanded 属性已设置为 true,则扩展器的内容在加载后不会再次测量。或者换句话说,当内容还没有实际大小时就对其进行测量。

我认为最简单的解决方案是在加载对话框后设置SelectedItem:

dialog.Loaded += (s, x) => vm.SelectedItem = item;

关于wpf - 第一次从绑定(bind)扩展时,ListBox 内的扩展器不显示内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16460417/

相关文章:

WPF DataBinding 与 RelativeSource 问题

c# - 检测是否在 NavigationContext 中调用了 GoBack()

asp.net - AWS SNSClient发布请求的超时错误

angular - 在组件之间共享数据(Angular 7)

silverlight - WP7 WrapPanel & MVVM

c# - 如何将内联样式注入(inject)到我的 WPF WebBrowser 中加载的文档中?

c#-4.0 - Web.Config 中的 Log4Net 部分生成错误

asp.net - 由于asp.net中对象的当前状态,因此操作无效。

silverlight - 为什么我得到不一致的绑定(bind)结果

C#,没有视频,只有音频,使用多种形式的 VLC,黑屏?