wyvern010
Topic Author
Posts: 31
Joined: 18 Apr 2019, 13:41

ListBox inside ListBox wont fire events

19 May 2019, 18:52

Hello again!

In my xaml i have a listbox, that listbox has an itemtemplate with another listbox.
I have binded a property to SelectedItem, and the get and set are getting called in WPF/Blend, but not in Noesis.
I also confirmed that the SelectedItem on the first listbox works as expected.
 <ListBox ScrollViewer.CanContentScroll="True"
                          ItemsSource="{Binding Sessions}"
                          Background="Black"
                          Focusable="False">
                    <ListBox.ItemTemplate>
                        <!--Session Data Template -->
                        <DataTemplate>
                            <Grid Focusable="False">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="50"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="10"/>
                                    <ColumnDefinition Width="20"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Text="{Binding SessionUITitle}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" TextAlignment="Left" HorizontalAlignment="Left" VerticalAlignment="Center" Focusable="False" Style="{StaticResource TextColor}"></TextBlock>
                                <ListBox x:Name="PresentationListBox" Grid.Row="1" Grid.Column="2"
                        ItemsSource="{Binding Presentations}"
                         Background="Transparent" SelectionMode="Single" SelectedItem="{Binding SelectedPresentation}">
                                    <ListBox.ItemTemplate>
                                        <!--Presentation Data Template -->
                                        <DataTemplate>
                                            <Grid>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="*"/>
                                                </Grid.RowDefinitions>
                                                <StackPanel Orientation="Horizontal" Height="120" VerticalAlignment="Center" Margin="10,0,0,0" Style="{StaticResource PresentationStackPanelStyle}">
                                                    <Rectangle Grid.Row="0" Grid.RowSpan="3" Width="8" Fill="{Binding StatusColor}"/>
                                                    <!-- File/Presentation status -->
                                                    <StackPanel Orientation="Vertical" Margin="20,0,0,0" VerticalAlignment="Center">
                                                        <TextBlock Text="{Binding Start}" Style="{StaticResource TextColor}" Margin="0,10,0,10"/>
                                                        <TextBlock Text="{Binding End}" Style="{StaticResource TextColor}"  Margin="0,10,0,10"/>
                                                    </StackPanel>
                                                    <StackPanel Orientation="Vertical" Margin="20,0,0,0" VerticalAlignment="Center">
                                                        <TextBlock Text="{Binding Subtitle}" Style="{StaticResource TextColor}" Margin="0,10,0,10"/>
                                                        <TextBlock Text="{Binding SpeakerNamesString}" Style="{StaticResource TextColor}" Margin="0,10,0,10"/>
                                                    </StackPanel>
                                                </StackPanel>
                                            </Grid>
                                        </DataTemplate>
                                    </ListBox.ItemTemplate>
                                </ListBox>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                
Is this the same bug as: viewtopic.php?f=3&t=1672 ?
 
wyvern010
Topic Author
Posts: 31
Joined: 18 Apr 2019, 13:41

Re: ListBox inside ListBox wont fire events

20 May 2019, 20:02

I got it partial fixed by hooking up the "SelectionChanged" event from the 2nd listbox.
But the binding to SelectedItem doesn't work.
 
User avatar
sfernandez
Site Admin
Posts: 3152
Joined: 22 Dec 2011, 19:20

Re: ListBox inside ListBox wont fire events

21 May 2019, 13:13

Is this the same bug as: viewtopic.php?f=3&t=1672 ?
No, it is not related. This seems to be a problem with data contexts.

Just to understand the scenario...you have a ViewModel with a list of Session objects, that is bound to the outer ListBox. Then each Session has a list of Presentation objects that is bound to the inner ListBox. I assume that each Session object exposes a SelectedPresentation property, is that correct? Because inside that template the active data context is the Session object itself.
 
wyvern010
Topic Author
Posts: 31
Joined: 18 Apr 2019, 13:41

Re: ListBox inside ListBox wont fire events

21 May 2019, 18:23

Yes, that is the case.
Every Session object has a SelectedPresentation Property.
And in wpf when i click on a presentation object the parent Session Object -> SelectedPresentation gets called/set.

PS: I do have to say that the actual data of the presentation itself is displayed corretly.
 
User avatar
sfernandez
Site Admin
Posts: 3152
Joined: 22 Dec 2011, 19:20

Re: ListBox inside ListBox wont fire events

22 May 2019, 13:42

I created a similar test and I'm not able to reproduce the problem, the SelectedPresentation setter gets called as expected.

Can you verify Session class implements INotifyPropertyChanged interface, and SelectedPresentation property is public with public getter and setter.

Here is my code:
    public class Presentation
    {
        public string Speaker { get; internal set; }
    }

    public class PresentationCollection : ObservableCollection<Presentation> { }

    public class Session : INotifyPropertyChanged
    {
        public string Title { get; internal set; }

        public PresentationCollection Presentations { get; private set; }

        private Presentation selectedPresentation;
        public Presentation SelectedPresentation
        {
            get { return selectedPresentation; }
            set
            {
                if (selectedPresentation != value)
                {
                    selectedPresentation = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedPresentation"));
                }
            }
        }

        public Session()
        {
            Presentations = new PresentationCollection();
            selectedPresentation = null;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class SessionCollection : ObservableCollection<Session> { }

    public class ViewModel : INotifyPropertyChanged
    {
        public SessionCollection Sessions { get; private set; }

        private Session selectedSession;
        public Session SelectedSession
        {
            get { return selectedSession; }
            set
            {
                if (selectedSession != value)
                {
                    selectedSession = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedSession"));
                }
            }
        }

        public ViewModel()
        {
            Sessions = new SessionCollection();
            selectedSession = null;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ViewModel vm = new ViewModel();

            Session s0 = new Session { Title = "Session 0" };
            s0.Presentations.Add(new Presentation { Speaker = "Mike" });
            s0.Presentations.Add(new Presentation { Speaker = "John" });
            s0.Presentations.Add(new Presentation { Speaker = "Steve" });
            vm.Sessions.Add(s0);

            Session s1 = new Session { Title = "Session 1" };
            s1.Presentations.Add(new Presentation { Speaker = "Anna" });
            s1.Presentations.Add(new Presentation { Speaker = "Elsa" });
            s1.Presentations.Add(new Presentation { Speaker = "Donna" });
            s1.Presentations.Add(new Presentation { Speaker = "Sarah" });
            vm.Sessions.Add(s1);

            DataContext = vm;
        }

        private void InitializeComponent()
        {
            Noesis.GUI.LoadComponent(this, "MainWindow.xaml");
        }
    }
<Window x:Class="App1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Foreground="White">
    <Grid>
        <ListBox Width="200" Height="300" ItemsSource="{Binding Sessions}" SelectedItem="{Binding SelectedSession}" Focusable="False">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Rectangle Fill="Red" Height="5"/>
                        <TextBlock Text="{Binding Title}"/>
                        <Rectangle Fill="Red" Height="1"/>
                        <ListBox ItemsSource="{Binding Presentations}" SelectedItem="{Binding SelectedPresentation}" Margin="20,0">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Speaker}"/>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="10">
            <TextBlock Text="{Binding Sessions.Count}"/>
            <TextBlock Text="{Binding SelectedSession.Title}"/>
            <TextBlock Text="{Binding SelectedSession.Presentations.Count}"/>
            <TextBlock Text="{Binding SelectedSession.SelectedPresentation.Speaker}"/>
        </StackPanel>
    </Grid>
</Window>

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests