[Version 2.0] View isn't refreshing when ViewModel properties change

Mar 12, 2012 at 8:31 PM

Thanks for the inital release Ado!

I now have my anchorables working by adding viewmodels to the AnchorablesSource collection :)

The first thing I came across is as the discussion Name suggests. I have a list in my View that is bound to a List<> in the ViewModel.

When the List<> is changed in the ViewModel I call "OnPropertyChanged("<property name>");" to update the View which doesn't refresh.

The View *does* refresh as soon as I start dragging the Anchorable (as a) floating window though... 

Steve

Mar 13, 2012 at 11:28 AM

Hi Steve,
this bug looks interesting (maybe is someting related to the content presenter I use anchorables), could you please package a short sample project showing the issue?

Is the problen occurring only with lists or also with simple types?

Ado

 

Mar 13, 2012 at 1:33 PM

 

Hi Ado,

I changed your example to show what I mean. WPF looks like it is throwing a validation error because there is a red line under the menu after you hit refresh.

The list doesn't refresh until you drag the anchorable or switch to the other one and switch back.

New MainWaindow:

 

<Window x:Class="AvalonDock.MVVMTestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:avalonDock="clr-namespace:AvalonDock;assembly=AvalonDock"
        xmlns:avalonDockControls="clr-namespace:AvalonDock.Controls;assembly=AvalonDock"
        xmlns:avalonDockLayout="clr-namespace:AvalonDock.Layout;assembly=AvalonDock"
        xmlns:local="clr-namespace:AvalonDock.MVVMTestApp"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">
    
    <Grid>
        
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <Menu>
            <MenuItem Header="File">
                <MenuItem Header="New" Command="{Binding NewCommand}"/>
                <MenuItem Header="Open" Command="{Binding OpenCommand}"/>
                <Separator/>
                <MenuItem Header="Save" Command="{Binding SaveCommand}"/>
                <MenuItem Header="Save As..." Command="{Binding SaveAsCommand}"/>
                <Separator/>
                <MenuItem Header="Close" Command="{Binding CloseCommand}"/>
            </MenuItem>
        </Menu>
        
        <avalonDock:DockingManager x:Name="dockManager" 
                                   DocumentsSource="{Binding Files}"
                                   AnchorablesSource="{Binding Tools}"
                                   ActiveContent="{Binding ActiveDocument, Mode=TwoWay}"
                                   DocumentCloseCommand="{Binding CloseCommand}"
                                   Grid.Row="1">
            
            <avalonDock:DockingManager.DocumentTemplateSelector>
                <local:DocumentTemplateSelector>
                    <local:DocumentTemplateSelector.FileViewTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding TextContent, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </local:DocumentTemplateSelector.FileViewTemplate>
                    <local:DocumentTemplateSelector.FileStatsViewTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="{Binding FileSize}"/>
                                <TextBlock Text="{Binding LastModified}"/>
                            </StackPanel>
                        </DataTemplate>
                    </local:DocumentTemplateSelector.FileStatsViewTemplate>
                </local:DocumentTemplateSelector>
            </avalonDock:DockingManager.DocumentTemplateSelector>
            
            <avalonDock:DockingManager.DocumentHeaderTemplateSelector>
                <local:DocumentTemplateSelector>
                    <local:DocumentTemplateSelector.FileViewTemplate>
                        <DataTemplate>
                            <Border>
                                <TextBlock Text="{Binding Path=Content.FileName}"/>
                            </Border>
                        </DataTemplate>
                    </local:DocumentTemplateSelector.FileViewTemplate>
                    <local:DocumentTemplateSelector.FileStatsViewTemplate>
                        <DataTemplate>
                            <Border>
                                <TextBlock Text="{Binding Path=Content.Name}"/>
                            </Border>
                        </DataTemplate>
                    </local:DocumentTemplateSelector.FileStatsViewTemplate>
                </local:DocumentTemplateSelector>
            </avalonDock:DockingManager.DocumentHeaderTemplateSelector>
            
            <avalonDock:DockingManager.DocumentTitleTemplateSelector>
                <local:DocumentTemplateSelector>
                    <local:DocumentTemplateSelector.FileViewTemplate>
                        <DataTemplate>
                            <Border>
                                <TextBlock Text="{Binding Path=Content.FileName}"/>
                            </Border>
                        </DataTemplate>
                    </local:DocumentTemplateSelector.FileViewTemplate>
                    <local:DocumentTemplateSelector.FileStatsViewTemplate>
                        <DataTemplate>
                            <Border>
                                <TextBlock Text="{Binding Path=Content.Name}"/>
                            </Border>
                        </DataTemplate>
                    </local:DocumentTemplateSelector.FileStatsViewTemplate>
                </local:DocumentTemplateSelector>
            </avalonDock:DockingManager.DocumentTitleTemplateSelector>

            <avalonDock:DockingManager.DocumentTitleTemplate>
                <DataTemplate>
                    <Border>
                        <TextBlock Text="{Binding Path=Content.FileName}"/>
                    </Border>
                </DataTemplate>
            </avalonDock:DockingManager.DocumentTitleTemplate>
            
            <avalonDock:DockingManager.AnchorableTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding FileSize}"/>
                        <TextBlock Text="{Binding LastModified}"/>
                        <Button Content="Refresh List" Command="{Binding Path=RefreshCommand}" />
                        <ListBox AlternationCount="2" Background="#FFF5B6B6" Margin="1,0,-1,0" Height="200"
                                    ItemsSource="{Binding Path=ListItems}" >
                        </ListBox>
                    </StackPanel>
                </DataTemplate>
            </avalonDock:DockingManager.AnchorableTemplate>
            
            <avalonDock:DockingManager.AnchorableHeaderTemplate>
                <DataTemplate>
                    <Border>
                        <TextBlock Text="{Binding Path=Content.Name}"/>
                    </Border>
                </DataTemplate>
            </avalonDock:DockingManager.AnchorableHeaderTemplate>
            
            <avalonDock:DockingManager.AnchorableTitleTemplate>
                <DataTemplate>
                    <Border>
                        <TextBlock Text="{Binding Path=Content.Name}"/>
                    </Border>
                </DataTemplate>
            </avalonDock:DockingManager.AnchorableTitleTemplate>

            <avalonDockLayout:LayoutRoot>
                <avalonDockLayout:LayoutPanel>
                    <avalonDockLayout:LayoutDocumentPane/>
                    <avalonDockLayout:LayoutAnchorablePane DockWidth="150">
                    </avalonDockLayout:LayoutAnchorablePane>
                </avalonDockLayout:LayoutPanel>
            </avalonDockLayout:LayoutRoot>
        </avalonDock:DockingManager>

    </Grid>
</Window>

 

New ToolViewModel:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AvalonDock.MVVMTestApp
{
    class ToolViewModel : ViewModelBase
    {

        private List<string> _listItems;

        private RelayCommand _refreshCommand;



        public List<string> ListItems
        {
            get
            {
                if (_listItems == null)
                    _listItems = new List<string>();
                return _listItems;
            }
        }

        public RelayCommand RefreshCommand
        {
            get
            {
                if (_refreshCommand == null) { _refreshCommand = new RelayCommand(c => Refresh()); }
                return _refreshCommand;
            }
        }

        private void Refresh()
        {

            _listItems.Clear();

            _listItems.Add("List Item 1");
            _listItems.Add("List Item 2");
            _listItems.Add("List Item 3");
            _listItems.Add("List Item 4");
            _listItems.Add("List Item 5");

            RaisePropertyChanged("ListItems");

        }


        public ToolViewModel(string name)
        {
            Name = name;
        }

        public string Name
        {
            get;
            private set;
        }
    }
}

Steve

 

Mar 13, 2012 at 1:47 PM

 

Oh and yes, it is just the list - I have a label that refreshes just fine.

Steve