Link to home
Start Free TrialLog in
Avatar of MarcoCastro
MarcoCastroFlag for Brazil

asked on

Is there a way to create a WPF UserControl with an available grid in it?

Hi,

   I need to create a WPF UserControl (or Control) that has two parts: a header with a Title and a grid right above it. The glitch is: I need to have access to this grid. I need to paste components in this grid. The component works right a Window with a header.

   My idea is create a constant part of the component (the header - the Title is a property) and variable part of it (the grid).

   Is is possible? How?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
namespace McSoft.WPF.Controls
{
  /// <summary>
  /// Interaction logic for McBorder.xaml
  /// </summary>
  public partial class McBorderLookless : Control
  {
    public McBorderLookless()
    {
      SetupBindings();
    }
 
    private void SetupBindings()
    {
      MultiBinding binding = new MultiBinding();
 
      Binding titleBinding = new Binding("Title");
      titleBinding.Source = this;
      titleBinding.Mode = BindingMode.TwoWay;
      binding.Bindings.Add(titleBinding);
 
      Binding gridBinding = new Binding("BorderGrid");
      gridBinding.Source = this;
      gridBinding.Mode = BindingMode.TwoWay;
      binding.Bindings.Add(gridBinding);
    }
 
    static McBorderLookless()
    {
      DefaultStyleKeyProperty.OverrideMetadata(typeof(McBorderLookless),
        new FrameworkPropertyMetadata(typeof(McBorderLookless)));
      TitleProperty = DependencyProperty.Register("Title", typeof(string),
                typeof(McBorderLookless),
                new FrameworkPropertyMetadata("Type title...", new PropertyChangedCallback(OnTitleChanged)));
      GridProperty = DependencyProperty.Register("BorderGrid", typeof(Grid),
                typeof(McBorderLookless),
                new FrameworkPropertyMetadata(new PropertyChangedCallback(OnGridChanged)));
    }
 
    // Tratando o título do border
    public static DependencyProperty TitleProperty;
 
    public string Title
    {
      get { return (string)GetValue(TitleProperty); }
      set { SetValue(TitleProperty, value); }
    }
 
    private static void OnTitleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
      McBorderLookless mcBorder = (McBorderLookless)sender;
      string newValue = (string)e.NewValue;
      mcBorder.Title = newValue.ToString();
    }
 
    // Tratando o grid do border
    public static DependencyProperty GridProperty;
 
    public Grid BorderGrid
    {
      get { return (Grid)GetValue(GridProperty); }
      set { SetValue(GridProperty, value); }
    }
 
    private static void OnGridChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
      McBorderLookless mcBorder = (McBorderLookless)sender;
      Grid newValue = (Grid)e.NewValue;
      mcBorder.BorderGrid = newValue;
    }
  }
}
 
--------------------
 
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
										xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
										xmlns:local="clr-namespace:McSoft.WPF.Controls">
	<Style TargetType="{x:Type local:McBorderLookless}">
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type local:McBorderLookless}">
					<Border CornerRadius="8" BorderThickness="2" BorderBrush="Gray" Grid.RowSpan="3">
						<Grid>
							<Grid.RowDefinitions>
								<RowDefinition Height="36" />
								<RowDefinition Height="225*" />
								<RowDefinition Height="36" />
							</Grid.RowDefinitions>
							<Label Name="lblTitle" HorizontalAlignment="Left" Margin="6" FontWeight="Bold" 
								VerticalAlignment="Stretch" Content="{Binding Path=Title,RelativeSource={RelativeSource TemplateParent}}"></Label>
							<Path Stretch="Fill" Margin="4,0,4,4" VerticalAlignment="Bottom" Height="2" 
								Data="M4,30 L273,30" StrokeThickness="2" Fill="{x:Null}">
								<Path.Stroke>
									<LinearGradientBrush EndPoint="0.738,0.24" StartPoint="0.201,0.25">
										<GradientStop Color="#FF000000" Offset="0"/>
										<GradientStop Color="#FFF9F9F9" Offset="1"/>
									</LinearGradientBrush>
								</Path.Stroke>
							</Path>
							<Grid Name="VoidGrid" Margin="0,0,0,0" Grid.Row="1" />
						</Grid>
					</Border>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
</ResourceDictionary>

Open in new window

Avatar of MarcoCastro
MarcoCastro
Flag of Brazil image

ASKER

What comes here: <Grid Name="VoidGrid" Margin="0,0,0,0" Grid.Row="1" />
I need to address this grid in the code. What is the name of the content of grid?
Sure.  Create the usercontrol.  Add the grid and title controls to the usercontrol.  Then encapsulate the functionality of the grid and the title control into the usercontrol.

The name of the grid is VoidGrid.  It should be available in the .xaml.vb code file.
I would derive a control from a grid and add any control as a header.
Don't derive from grid.  Create a WPF UserControl.  Then add a grid and textblock or label to it.
How I make the grid available to the users? It is VoidGrid. How I bind it to the code? The header is part of the component and the grid is another part. The grid is like a hole in the component. You can drop components into it. I want, as example, create RowDefinitions in the grid part of the component when an aplication is using the component.

Le me explain my wish in a photo. In the left picture is the component when I use it in a Window or Page. The right picture has the component in the Window with extra components that I droped into the component. If I move the component the labels moves as well.
Component.png
How can I bind to Grid.Children, since Children is ReadOnly.
ASKER CERTIFIED SOLUTION
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It seem to be not possible to implement my idea.