Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ViewModel Data Binding not working when Changing a ListBox's Data Template via a Trigger

I am having an issue when using a Trigger to change a ListBox's Data Template for the selected item.

When an item in the ListBox control is selected, I use a trigger to swap out the Data Template so that I can show additional controls, including a ComboBox. Unfortunately when the Data Template switches to the SelectedArticleDataTemplate, the ComboBox's Data Bindings do not seem to work. I am Binding to an Observable Collection in the ViewModel for the ItemSource, as well as a property for the Selected Item. INotifyPropertyChanged is implemented on all Properties in the VieModel and associated Models.

Here is a snippet of the code:

<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>

For testing purposes, I added the following code outside of the Data Template and it worked perfectly:

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

What am I missing?

Thanks

EDIT:

The ListBox has a Data Binding to an ObservableCollection of Articles (Target Weights, Tolerances etc.) in the ViewModel. When a user selects an article, I want to let them choose, via the ComboBox, which Scale Group to transmit the article to. - I hope that makes sense.

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

In my MainViewModel I have the following properties:

        /// <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");
            }
        }

ANSWER:

Thanks to Clemens for persisting with me.

The following change made all the difference:

<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" />
like image 610
Phil T Avatar asked Nov 20 '25 14:11

Phil T


1 Answers

Thanks to Clemens for persisting with me.

The following change made all the difference:

<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" />
like image 104
Phil T Avatar answered Nov 23 '25 04:11

Phil T