Skip to content

Commit

Permalink
[Editor API] - Added function to assign a data context (view model) t…
Browse files Browse the repository at this point in the history
…o the current hosted control without knowing the type of control or type of view model.
  • Loading branch information
Tape-Worm committed Jan 22, 2022
1 parent fd821ee commit c9f8385
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 6 deletions.
18 changes: 18 additions & 0 deletions Tools/Editor/Gorgon.Editor.API/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Tools/Editor/Gorgon.Editor.API/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,10 @@ These platforms are incompatible and cannot be mixed.</value>
<value>The file '{0}' already exists.
Would you like to overwrite it?</value>
</data>
<data name="GOREDIT_ERR_HOSTED_CTL_NOT_DATACONTEXT" xml:space="preserve">
<value>The hosted control '{0}' does not accept data contexts.</value>
</data>
<data name="GOREDIT_ERR_INVALID_DATACONTEXT_TYPE" xml:space="preserve">
<value>The data context type '{0}' cannot be used with the hosted control.</value>
</data>
</root>
36 changes: 31 additions & 5 deletions Tools/Editor/Gorgon.Editor.API/UI/ViewFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ public static void Unregister<T>()
/// </remarks>
public static void AssignViewModel(IViewModel viewModel, Control control)
{
if (viewModel is null)
{
throw new ArgumentNullException(nameof(viewModel));
}

if (control is null)
{
throw new ArgumentNullException(nameof(control));
Expand All @@ -119,6 +114,37 @@ public static void AssignViewModel(IViewModel viewModel, Control control)
method?.Invoke(control, new[] { viewModel });
}

/// <summary>
/// Function to retrieve the view model assigned to a control.
/// </summary>
/// <param name="control">The control to evaluate.</param>
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="control"/> parameter is <b>null</b>.</exception>
/// <exception cref="InvalidCastException">Thrown if the <paramref name="control"/> parameter does not implement <see cref="IDataContext{T}"/>.</exception>
/// <remarks>
/// <para>
/// This will return the view model assigned to the specified <paramref name="control"/>. If the control does not implement <see cref="IDataContext{T}"/>, then an exception will be thrown.
/// </para>
/// </remarks>
public static IViewModel GetViewModel(Control control)
{
if (control is null)
{
throw new ArgumentNullException(nameof(control));
}

Type dataContextType = typeof(IDataContext<>);
Type controlType = control.GetType();
Type controlInterface = controlType.GetInterface(dataContextType.FullName);

if (controlInterface is null)
{
throw new InvalidCastException(string.Format(Resources.GOREDIT_ERR_HOSTED_CTL_NOT_DATACONTEXT, control.Name));
}

PropertyInfo property = controlInterface.GetProperty("DataContext");
return property?.GetValue(control) as IViewModel;
}

/// <summary>
/// Function to determine if the view model type has a view registration.
/// </summary>
Expand Down
54 changes: 53 additions & 1 deletion Tools/Editor/Gorgon.Editor.API/UI/Views/ContentBaseControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ public event EventHandler<DragEventArgs> BubbleDragDrop
#endregion

#region Properties.
/// <summary>
/// Property to return the currently hosted panel in the <see cref="HostPanelControls"/>.
/// </summary>
protected Control CurrentHostedPanel
{
get;
private set;
}

/// <summary>
/// Property to set or return the idle method for rendering on the control.
/// </summary>
Expand Down Expand Up @@ -461,6 +470,8 @@ protected void ShowHostedPanel(Control control)
PanelHostControls.Visible = PanelHost.Visible = true;
control.Visible = true;
PanelHostControls.AutoScrollMinSize = new Size(0, control.Height);

CurrentHostedPanel = control;
}
finally
{
Expand Down Expand Up @@ -539,7 +550,48 @@ protected void HideHostedPanels()
control.Visible = false;
}

PanelHost.Visible = PanelHostControls.Visible = false;
PanelHost.Visible = PanelHostControls.Visible = false;

CurrentHostedPanel = null;
}

/// <summary>
/// Function to assign a data context to the <see cref="CurrentHostedPanel"/>.
/// </summary>
/// <param name="dataContext">The data context to assign.</param>
/// <param name="overrideCurrentDc"><b>true</b> to replace any non-null data context if present, or <b>false</b> to leave the current data context in place.</param>
/// <exception cref="InvalidCastException">Thrown when the <see cref="CurrentHostedPanel"/> does not accept the type of data context represented by <paramref name="dataContext"/>.
/// <para>-or-</para>
/// <para>Thrown if the <see cref="CurrentHostedPanel"/> does not implement <see cref="IDataContext{T}"/>.</para>
/// </exception>
/// <remarks>
/// <para>
/// This method is used to assign an instance of a data context to the hosted panel in the <see cref="HostPanelControls"/>. If the panel does not implement <see cref="IDataContext{T}"/>, or the type of data
/// context does not match the type of data context the control was built for, an exception will be thrown.
/// </para>
/// </remarks>
protected void AssignDataContextToHostedPanel(IViewModel dataContext, bool overrideCurrentDc)
{
if (CurrentHostedPanel is null)
{
return;
}

Type dataContextType = typeof(IDataContext<>);
Type controlType = CurrentHostedPanel.GetType();
Type controlInterface = controlType.GetInterface(dataContextType.FullName);

if (controlInterface is null)
{
throw new InvalidCastException(string.Format(Resources.GOREDIT_ERR_HOSTED_CTL_NOT_DATACONTEXT, CurrentHostedPanel.Name));
}

if ((!overrideCurrentDc) && (ViewFactory.GetViewModel(CurrentHostedPanel) is not null))
{
return;
}

ViewFactory.AssignViewModel(dataContext, CurrentHostedPanel);
}

/// <summary>
Expand Down

0 comments on commit c9f8385

Please sign in to comment.