This is a migrated thread and some comments may be shown as answers.

Loading layout breaks template bindings

1 Answer 132 Views
Docking
This is a migrated thread and some comments may be shown as answers.
Nikita
Top achievements
Rank 1
Nikita asked on 10 Mar 2015, 01:42 PM
Hello. I kind of necroposted in other thread about this issue. That thread seems to be inactive though, so I thought I might as well start a new one, and add some context.

So, long story short, I am trying to implement MVVM with RadDocking and I am having troubles with data binding. Whenever I call LoadLayout method all the binidings that were set in templates break, and i don't know how to fix them.

This is the global style, I'm applying to RadPanes:

<DataTemplate x:Key="HeaderTemplate">
    <StackPanel Orientation="Horizontal">
        <Image Margin="0,0,3,0" Source="{Binding Screen.IconSource}" Width="16" Height="16""/>
        <TextBlock Text="{Binding Screen.Title}"/>
    </StackPanel>
</DataTemplate>
 
<Style TargetType="{x:Type Controls:RadPane}">
    <Setter Property="HeaderTemplate" Value="{StaticResource HeaderTemplate}"/>
    <Setter Property="TitleTemplate" Value="{StaticResource HeaderTemplate}"/>
</Style>

This is my viewmodel class which represents a single pane:
public class ScreenViewModel
{
        public ScreenViewModel(IScreen screen)
        {
            Screen = screen;
        }
 
        public IScreen Screen { get; private set; }
         
        private RadPane _pane;
          //this property is set in DockingPanesFactory.CreatePaneForItem method
        public RadPane Pane
        {
            get { return _pane; }
            set
            {
                _pane = value;
                _pane.Content = Screen.View;
                _pane.Header = this;
                RadDocking.SetSerializationTag(_pane, Screen.ContentId);
            }
        }
//+some other irrelevant properties
}
 
//this is my model
interface IScreen
{
    UIElement View { get; }
    string Title { get; }
    string ContentId { get; }
    ImageSource IconSource { get; }
}

And this is how I load the layout:
public ObservableCollection<ScreenViewModel> Screens { get; set; }
 
public void Load(string file, IScreenFactory screenFactory)
{
    if (!File.Exists(file)) return;
    Screens.Clear();
    using (var fs = File.OpenRead(file))
    {
        var doc = XDocument.Load(fs);
        foreach (var screenId in doc.Descendants("RadPane").Select(x => x.Attribute("SerializationTag").Value))
        {
            //some factory wich creates models by their IDs
            IScreen screen = screenFactory.RestoreScreen(screenId);
            Screens.Add(new ScreenViewModel(screen));
        }
        if (Screens.Any())
        {
            fs.Position = 0;
            //after this call all template the bindings break
            _radDocking.LoadLayout(fs);
        }
    }
}
After the LoadLayout call I can see that header content is set, and that the template is applied, but the bindings set by this template are broken (VS Output is flooded by binding exceptions), which results in empty pane headers. What am I doing wrong?

1 Answer, 1 is accepted

Sort by
0
Nikita
Top achievements
Rank 1
answered on 11 Mar 2015, 06:45 AM
Nevermind, I have figured this one out. In order for header template to work after LoadLayout call, you have to re-set RadPane.Header property in ElemntLoaded event handler. Setting it in DockingPanesFactory.CreatePaneForItem method is not enough, apparently.
Tags
Docking
Asked by
Nikita
Top achievements
Rank 1
Answers by
Nikita
Top achievements
Rank 1
Share this question
or