Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 532929
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T09:27:21+00:00 2026-05-13T09:27:21+00:00

UPDATED (12/17/2009): Now reflects latest progress I’ve made. This is the first application that

  • 0

UPDATED (12/17/2009): Now reflects latest progress I’ve made.

This is the first application that myself and a co-worker are developing using Prism and MVVM in Silverlight 3.0. I am working on a shell/framework for the project that will have a list of “plugins” that can be added to a “workspace”.

The plugins are registered with a WorkSpaceManager class during their particular PRISM IModule.Initialize() methods like so:

workspace.RegisterPlugin(new PluginInfo() { Name = "MyPlugin", ViewType = typeof(MyPluginView), SettingsViewType = null });

The RegisterPlugin() method simply adds the PluginInfo object to a dictionary keyed on the “Name” property. Then when I want to add a plugin to the workspace I do the following:

workspace.AddPluginToWorkspace("MyPlugin");

The AddPluginToWorkspace method of the WorkspaceManager class looks like this:

public void AddPluginToWorkspace(string pluginName)
    {
        if (AvailablePlugins.ContainsKey(pluginName))
        {
            PluginInfo pi = AvailablePlugins[pluginName];
            WorkspacePlugin wsp = new WorkspacePlugin();

            // Create the View
            wsp.View = (Control)this.unityContainer.Resolve(pi.ViewType);
            wsp.Name = pi.Name;

            // Wire up the CloseCommand to WorkspaceManager's PluginClosing handler
            wsp.CloseCommand = new DelegateCommand<WorkspacePlugin>(this.PluginClosing);

            // Add the plugin to the active plugins (modules) collection
            this.modules.Add(wsp);

            // FIX: This should notify anyone listening that the ActivePlugins have changed. When enabled, this causes the same error that will be mentioned further on when attempting to close a plugin.
            //this.eventAggregator.GetEvent<ActivePluginsChanged>().Publish(wsp);
        }

    }

The Workspace ViewModel simply exposes the WorkspaceManager Service’s modules collection which is the datacontext of the Workspace View as shown here:

<Grid x:Name="LayoutRoot"
      Background="White">
    <ListBox x:Name="ModuleListBox"
             Grid.Row="1"
             rgn:RegionManager.RegionName="Workspace"
             Background="Yellow"
             ItemsSource="{Binding Plugins}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.Template>
            <ControlTemplate>
                <Grid x:Name="ListBoxGrid">
                    <ItemsPresenter></ItemsPresenter>
                </Grid>
            </ControlTemplate>
        </ListBox.Template>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="Black"
                        BorderThickness="2"
                        Margin="0"
                        Padding="0">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20"></RowDefinition>
                            <RowDefinition Height="*"></RowDefinition>
                            <RowDefinition Height="5"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width=".05*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Button Content="X"
                                    HorizontalAlignment="Right"
                                    Grid.Column="1"
                                    cmd:Click.Command="{Binding CloseCommand}"
                                    cmd:Click.CommandParameter="{Binding}"></Button>
                        </Grid>
                        <Border BorderBrush="Black"
                                BorderThickness="2"
                                Margin="0"
                                VerticalAlignment="Center"
                                HorizontalAlignment="Center"
                                Grid.Row="1">
                            <tk:Viewbox Stretch="Uniform"
                                        StretchDirection="Both">
                                <ContentControl Content="{Binding View}"></ContentControl>                    
                            </tk:Viewbox>
                        </Border>                            
                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

Notice the Content control that is bound to the “View” property of the WorkspacePlugin and the Button that has the Click.Command bound to the “CloseCommand”. This is where I was stuck initially but for the most part, this works. The plugin’s view is loaded inside the other controls and I’m still able to bind the close command (And other commands to be added at a later time) to an underlying model.

The problem now is that whenever I click the close button and the WorkspacePlugin is removed from the modules collection, a property changed event is fired on the ViewModel to let the listbox know to update I get the following error (This also happens if I uncomment the line below the “FIX” comment above:

System.ArgumentException: Value does not fall within the expected range.
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.SetValue(INativeCoreTypeWrapper obj, DependencyProperty property, DependencyObject doh)
at MS.Internal.XcpImports.SetValue(INativeCoreTypeWrapper doh, DependencyProperty property, Object obj)
at System.Windows.DependencyObject.SetObjectValueToCore(DependencyProperty dp, Object value)
at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)
at System.Windows.Data.BindingExpression.RefreshExpression()
at System.Windows.Data.BindingExpression.SendDataToTarget()
at System.Windows.Data.BindingExpression.SourceAquired()
at System.Windows.Data.BindingExpression.DataContextChanged(Object o, DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive)
at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent, IManagedPeer newParent, Boolean bIsNewParentAlive, Boolean keepReferenceToParent)
at MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement, IntPtr parentElement, IntPtr childElement, Byte bIsParentAlive, Byte bKeepReferenceToParent)

From what I gather by looking online, this typically means that a visual element that was already added to the visual tree is trying to be added again. This kind of makes since if I only have 1 plugin displayed and close it, it disappears and there is no error. I am fairly certain that the error is due to the WorkspacePlugin.View property being a visual control and the binding update is attempting to re-add it to the visual tree.

How can I work around this or achieve the desired result without the error message?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T09:27:22+00:00Added an answer on May 13, 2026 at 9:27 am

    I ended up getting this working doing the following:

    I created a WorkspaceItemView view and ViewModel which look roughly like this:

    <UserControl>
    <Grid  x:Name="ResizeGrid"
           MouseEnter="Plugin_MouseEnter"
           MouseLeave="Plugin_MouseLeave">
        <Grid.RowDefinitions>
            <RowDefinition Height="20" />
            <RowDefinition Height="*" />
            <RowDefinition Height="5" />
        </Grid.RowDefinitions>
    
        <Border x:Name="border"
                BorderBrush="Black"
                BorderThickness="2"
                Padding="0"
                Margin="-1,-1,-1,-1">
        </Border>
    
        <Grid x:Name="grid"
              Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width=".05*" />
            </Grid.ColumnDefinitions>
            <Thumb HorizontalAlignment="Stretch"
                   Background="Green"
                   DragDelta="Thumb_DragDelta"
                   />
            <Button Content="X"
                    HorizontalAlignment="Right"
                    Grid.Column="1"
                    cmd:Click.Command="{Binding CloseCommand}"
                    cmd:Click.CommandParameter="{Binding PluginID}" />
        </Grid>
    
        <Border BorderBrush="Black"
                BorderThickness="2"
                Margin="0"
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Grid.Row="1">
            <tk:Viewbox Stretch="Uniform"
                        StretchDirection="Both">
                <ContentControl rgn:RegionManager.RegionName="PluginViewRegion" />
    
            </tk:Viewbox>
        </Border>
        <Thumb x:Name="SizeGrip"
               Grid.Row="1"
               VerticalAlignment="Bottom"
               HorizontalAlignment="Right"
               Width="10"
               Height="10"
               Margin="0,0,-7,-7"
               Style="{StaticResource SizeGrip}"
               DragDelta="SizeGrip_DragDelta"
               DragStarted="SizeGrip_DragStarted"
               DragCompleted="SizeGrip_DragCompleted" />
    
    </Grid>
    </UserControl>  
    

    public class WorkspaceItemViewModel : INotifyPropertyChanged
    {
        private IWorkspaceManager workspaceManager;
        private IRegionManager regionManager;
        private Guid pluginID;
    
        public WorkspaceItemViewModel(IWorkspaceManager workspaceManager, IRegionManager regionManager)
        {
            this.workspaceManager = workspaceManager;
            this.regionManager = regionManager;
        }
    
        public DelegateCommand<object> CloseCommand 
        {
            get
            {
                return workspaceManager.CloseCommand;
            }    
        }
    
        public DelegateCommand<object> SelectCommand
        {
            get
            {
                return workspaceManager.SelectCommand;
            }
        }
    
        public object CloseCommandParameter
        {
            get
            {
                return this;
            }
        }
    
        public Guid PluginID
        {
            get
            {
                return this.pluginID;
            }
            set
            {
                this.pluginID = value;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("PluginID"));
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    

    }

    The WorkspaceManager code to add a plug-in to the workspace looks like this:

    public void AddPluginToWorkspace(string pluginName)
        {
            PluginInfo pi = AvailablePlugins[pluginName];
            WorkspacePlugin wsp = new WorkspacePlugin();
            wsp.Name = pi.Name;
            wsp.CloseCommand = new DelegateCommand<object>(this.PluginClosing);
            wsp.SelectCommand = new DelegateCommand<object>(this.PluginSelected);
            wsp.id = System.Guid.NewGuid();
            this.modules.Add(wsp.id, wsp);
    
            var view = this.unityContainer.Resolve(pluginWindowType);
            if (view is IWorkspacePlugin)
            {
                var iwsp = view as IWorkspacePlugin;
                if (iwsp != null)
                {
                    iwsp.PluginID = wsp.id;
                }
            }
            else
            {
                throw new ArgumentException("Plugin view containers must implement IWorkspacePlugin.");
            }
    
            var workspaceRegion = regionManager.Regions["Workspace"];
            var pluginRegion = workspaceRegion.Add(view, wsp.id.ToString(), true);
            this.unityContainer.RegisterInstance<IRegionManager>(wsp.id.ToString(), pluginRegion);
            pluginRegion.Regions["PluginViewRegion"].Context = view;
            pluginRegion.Regions["PluginViewRegion"].Add(this.unityContainer.Resolve(pi.ViewType));
    
            this.eventAggregator.GetEvent<ActivePluginsChanged>().Publish(wsp);
    

    }

    This essentially creates a scoped region, adds the WorkspaceItemView to the workspace region and then resolves and adds the view of the actual plugin to the PluginViewRegion of the newly added WorkspaceItemView. I have a little bit of cleanup work to do but I think it works pretty well.

    Thanks for all of your help.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.