【问题标题】:WPF ViewModel Data Binding not working when Changing a ListBox's Data Template via a Trigger通过触发器更改列表框的数据模板时,WPF ViewModel 数据绑定不起作用
【发布时间】:2015-08-26 09:59:46
【问题描述】:

我在使用触发器更改所选项目的列表框数据模板时遇到问题。

当 ListBox 控件中的一个项目被选中时,我使用触发器来换出数据模板,以便我可以显示其他控件,包括 ComboBox。不幸的是,当数据模板切换到 SelectedArticleDataTemplate 时,组合框的数据绑定似乎不起作用。我正在为 ItemSource 绑定到 ViewModel 中的 Observable 集合,以及所选项目的属性。 INotifyPropertyChanged 在 VieModel 和关联模型中的所有属性上实现。

这是一个sn-p的代码:

<DataTemplate x:Key="ArticleDataTemplate">
    <TextBlock Text="{Binding Model.ArticleName}" FontSize="12" Margin="5" />
</DataTemplate>


 <DataTemplate x:Key="SelectedArticleDataTemplate">
     <StackPanel Margin="150,0,0,0">
         <StackPanel Orientation="Horizontal">
             <TextBlock Text="Select Scale Group :" Width="150" />
             <ComboBox Width="200" ItemsSource="{Binding ScaleGroups}" SelectedItem="{Binding SelectedGroup}" Margin="0,0,0,10" />
         </StackPanel>
     </StackPanel>
 </DataTemplate>


<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
    <Setter Property="ContentTemplate" Value="{StaticResource ArticleDataTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedArticleDataTemplate}"/>
        </Trigger>
    </Style.Triggers>
</Style>

出于测试目的,我在数据模板之外添加了以下代码,它运行良好:

<ComboBox Width="200" Margin="0,0,0,10"
          ItemsSource="{Binding ScaleGroups}" 
          SelectedItem="{Binding SelectedGroup}" />

我错过了什么?

谢谢

编辑:

ListBox 具有与 ViewModel 中文章(目标权重、公差等)的 ObservableCollection 的数据绑定。当用户选择一篇文章时,我想让他们通过 ComboBox 选择要将文章传输到哪个 Scale Group。 - 我希望这是有道理的。

 <ListBox Width ="863" Margin="5" Height="422"
          IsSynchronizedWithCurrentItem="True"   
          ItemsSource="{Binding Articles}" 
          SelectedItem="{Binding SelectedArticle}"  
          ItemContainerStyle="{StaticResource ContainerStyle}"
          Background="#FFEAF0FF" />

在我的 MainViewModel 中,我具有以下属性:

        /// <summary>
        /// List of Scale Groups
        /// </summary>
        public ObservableCollection<string> ScaleGroups
        {
            get { return scaleGroups; }
            set
            {
                scaleGroups = value;
                RaisePropertyChanged("ScaleGroups");
            }
        }

        /// <summary>
        /// Selected Scale Group
        /// </summary>
        public string SelectedGroup
        {
            get { return selectedGroup; }
            set
            {
                selectedGroup = value;
                RaisePropertyChanged("SelectedGroup");
            }
        }

        /// <summary>
        /// List of Articles
        /// </summary>
        public ObservableCollection<ArticleViewModel> Articles
        {
            get { return articles; }
            set
            {
                articles = value;

                ApplyCollectionFilter();
                RaisePropertyChanged("Articles");
            }
        }

        /// <summary>
        /// Selected Article
        /// </summary>
        public ArticleViewModel SelectedArticle
        {
            get { return selectedArticle; }
            set
            {
                selectedArticle = value;
                RaisePropertyChanged("SelectedArticle");
            }
        }

回答:

感谢克莱门斯对我的坚持。

以下更改使一切变得不同:

<ComboBox Width="250" 
          ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.ScaleGroups}" 
          SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.SelectedGroup}" 
          IsSynchronizedWithCurrentItem="True" Margin="0,0,0,10" />

【问题讨论】:

  • 您真的想将所选 ListBoxItem 的 DataTemplate 中的 ComboBox 绑定到与 ListBox 本身相同的 ScaleGroups 集合吗?
  • 感谢您回复克莱门斯。 ListBox 具有与文章的 ObservableCollection(目标权重、公差等)的数据绑定。当我选择一篇文章时,我想让用户通过 ComboBox 选择要将文章传输到哪个 Scale Group。
  • ListBox 没有绑定到 ScaleGroup 属性。我添加了额外的代码,希望能让事情变得更清楚。谢谢
  • DataTemplate 中控件的 DataContext 设置为源集合的单个项目,即此处的 Article 实例(这就是 {Binding Model.ArticleName} 起作用的原因)。因此,ScaleGroups 属性也应该在 Article 类中。
  • 否则你应该可以通过ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.ScaleGroups}"绑定到“外部”视图模型。 SO上有很多关于这个主题的问答。

标签: c# wpf mvvm viewmodel


【解决方案1】:

感谢克莱门斯对我的坚持。

以下更改使一切变得不同:

<ComboBox Width="250" 
          ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.ScaleGroups}" 
          SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=DataContext.SelectedGroup}" 
          IsSynchronizedWithCurrentItem="True" Margin="0,0,0,10" />

【讨论】:

    猜你喜欢
    • 2014-04-04
    • 2013-02-23
    • 2010-11-29
    • 1970-01-01
    • 2018-02-02
    • 2011-02-05
    • 2014-01-13
    • 2014-08-06
    • 2011-11-21
    相关资源
    最近更新 更多