0
votes

I would like to created listbox with ItemsSource and SelectedItem binding on model object.

The Binding is done as following :

  <ItemsControl ItemsSource="{Binding Persons}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Name}" Width="150" />
                    <ListBox 
                        BorderThickness="0"
                        Background="Transparent"
                        Margin="0 1"
                        ItemsSource="{Binding DataContext.Skills,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Mode=OneWay}"
                        SelectedItem="{Binding MasterSkill, Mode=TwoWay}"
                        SelectionMode="Single"
                        ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                        >
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

On the first load it works, the value are selected with the default registered data.

The problem appear after switch/reload the current viewModel UI. When i come back to the ViewModel SelectItem is null.

The values seems update on/after leaving the UI (on the unload). The problem disappear when i use delay(>0) property or when i set UpdateSourceTrigger to LostFocus

I created an exemple of my problem on Github => here (In the exemple you have to go on "Manage Skills" windows and switch to "Manage project" to finally return to the skills)

I think the UI thread call the event propertyChanged when the control is unload or destroyed... but i don't really know how to avoid this problem.

Thanks a lot for your help.

1
Welcome to StackOverflow! It is perfectly reasonable (and actually highly advised for a question to be of good quality) to share some code like you did; the one additional requirement is to directly paste your code into your question, of course selecting the only sections needed. - Francesco B.
Seeing your code on github repo, I can clearly say that you have issues with NavigateTo method and GoToProj &GoToSkills properties. Everytime, you are creating a new object of the ViewModel instead of returning the old initialized object. So since, you are returning new object a new View is created everytime that's means you will loose the state of previous instance of view of same type. - user1672994
Yes i would like to recreate the view. But in my case the data are stored behind (via the dataProvider). So if i reload new UI with data stored, they have not to be null. When i put breakpoint on the set, he seems to be call when with null value when i leave the current ViewModel. - Lionhart34
There is a difference, creating a new vs re-initializing a existing view. Since, you are creating a new object of ViewModel, a new instance of View is also being created. So all the state of selected item is getting lost. - user1672994
In my case, i recreate view with data retrieve from service or other. After modify data in my view i stored them. If i recreate new view and get data from the service/database, the value do not have to be empty. If i replace my Listbox by a TextBlock as following '<TextBlock Text="{Binding Path=MasterSkill.ShortName}" Width="150" />' the value is not erase. The listbox binding erase my SelectedItem by null value when leaving UI don't know why this behavior. If i use mode LostFocus it works but i would like to use OnPropertyChanged option. - Lionhart34

1 Answers

0
votes

In the code that you pasted, everytime when you click on the buttons you are creating new instances of the viewmodel, which means the existing values will be flushed out. The same is the case for both the UIs.

switch (targetViewModel)
            {
                case "1":
                    CurrentViewModel = new ProjectViewModel();
                    break;
                case "2":
                    CurrentViewModel = new ManageSkillsViewModel();
                    break;
                default:
                    CurrentViewModel = null;
                    break;
            }

This is the section i am talking about. Instead i feel like you don't need to create instances like this and if any time you need to have something like loading a fresh VM you can try clearing the existing values.