Hide grid row in WPF - wpf

I have a simple WPF form with a Grid declared on the form. This Grid has a bunch of rows:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Height="Auto" Name="rowToHide" />
<RowDefinition Height="Auto" MinHeight="30" />
</Grid.RowDefinitions>
The row named rowToHide contains a few input fields and I want to hide this row after I detect I don't need these fields. It's simple enough to just set Visibility = Hidden to all items in the row, but the row still takes up space in the Grid. I tried setting Height = 0 to the items, but that didn't seem to work.
You can think of it like this: You have a form, in there you have a drop down saying "Payment Type", and if the person selects "Cash", you want to hide the row containing the Card details. It isn't an option to start the form with this hidden already.

Row does not have a Visibility property, so as others have said, you need to set the Height. Another option is to use a converter, in case you need this functionality in many views:
[ValueConversion(typeof(bool), typeof(GridLength))]
public class BoolToGridRowHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value == true) ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{ // Don't need any convert back
return null;
}
}
And then in the appropriate view <Grid.RowDefinition>:
<RowDefinition Height="{Binding IsHiddenRow, Converter={StaticResource BoolToGridRowHeightConverter}}"></RowDefinition>

The best and clean solution to collapse rows or columns is to use a DataTrigger so in your case:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Name="rowToHide">
<RowDefinition.Style>
<Style TargetType="{x:Type RowDefinition}">
<Setter Property="Height" Value="Auto" />
<Style.Triggers>
<DataTrigger Binding="{Binding SomeBoolProperty}" Value="True">
<Setter Property="Height" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</RowDefinition.Style>
</RowDefinition>
<RowDefinition Height="Auto" MinHeight="30" />
</Grid.RowDefinitions>
</Grid>

You can also do this by referencing the Row in the Grid and then changing the Height of the row itself.
XAML
<Grid Grid.Column="2" Grid.Row="1" x:Name="Links">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
</Grid>
VB.NET
If LinksList.Items.Count > 0 Then
Links.RowDefinitions(2).Height = New GridLength(1, GridUnitType.Star)
Else
Links.RowDefinitions(2).Height = New GridLength(0)
End If
Whilst the Collapsing of the elements within the Grid also works, this is a bit simpler if you have many items in the Grid that does not have an enclosing element that can be collapsed. This would provide a good alternative.

For reference, Visibility is a three-state System.Windows.Visibility enumeration:
Visible - The element gets rendered and participates in layout.
Collapsed - The element is invisible and does not participate in layout. Effectively giving it a height and width of 0 and behaving as if it doesn't exist.
Hidden - The element is invisible but continues to participate in layout.
See this tip and other tips on the WPF Tips and Tricks thread.

Instead of fiddling with the Grid Row, you can set the Visibility property of the Controls (fields in the row) to "Collapsed". This will ensure that the controls don't take up any space and if you have Grid Row Height="Auto", then the row will be hidden as all the controls in the row have Visibility="Collapsed".
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" Name="rowToHide" />
</Grid.RowDefinitions>
<Button Grid.Row=0 Content="Click Me" Height="20">
<TextBlock Grid.Row=1
Visibility="{Binding Converter={StaticResource customVisibilityConverter}}" Name="controlToHide"/>
</Grid>
This method is better because the Visibility of the controls can be bound to some property with the help of a Converter.

Simply do this:rowToHide.Height = new GridLength(0);
if u will use visibility.Collapse then u have to set it for every member of the row.

Set the Row's content visibility to Visibility.Collapsed instead of Hidden. This will make the content stop taking up space, and the row will shrink appropriately.

I had a similar idea by inheriting RowDefinition (just for interest)
public class MyRowDefinition : RowDefinition
{
private GridLength _height;
public bool IsHidden
{
get { return (bool)GetValue(IsHiddenProperty); }
set { SetValue(IsHiddenProperty, value); }
}
// Using a DependencyProperty as the backing store for IsHidden. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsHiddenProperty =
DependencyProperty.Register("IsHidden", typeof(bool), typeof(MyRowDefinition), new PropertyMetadata(false, Changed));
public static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var o = d as MyRowDefinition;
o.Toggle((bool)e.NewValue);
}
public void Toggle(bool isHidden)
{
if (isHidden)
{
_height = this.Height;
this.Height = new GridLength(0, GridUnitType.Star);
}
else
this.Height = _height;
}
}
Now you can use it as following:
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<my:MyRowDefinition Height="4*" IsHidden="false" x:Name="RowToHide" />
<RowDefinition Height="*" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
and toggle with
RowToHide.IsHidden = !RowToHide.IsHidden;

Related

Setting margin to controls outside Grid with reference to control inside Grid

Working on wpf solution
i have created a Grid with different columns, a control is added in column 2.
Now i have a control outside grid and the Left margin should be same as the control inside the grid.
Can this be done?
We can of course take the very simple way of changing Margin using code.
For pure MVVM approach, you can do that using AttachedProperty.
Binding with a Convertor won't work here as Thickness type is not a DependencyObject.
If we simply bind the Margin of outer Button to inner Button, Entire Margin of outer Button will change, which we dont want. So, we need to preserve whole Margin except Left Margin. Left Margin can be changed using Binding. But how ? Our outer Button needs to have two Margin values, one original, and another coming from inner Button, so that original one can be changed. For this another margin, we can take help of Attached Property, as they allow us to extend a control.
AttachedProperty
public static BindingExpression GetLefMargin(DependencyObject obj)
{
return (BindingExpression)obj.GetValue(LefMarginProperty);
}
public static void SetLefMargin(DependencyObject obj, BindingExpression value)
{
obj.SetValue(LefMarginProperty, value);
}
// Using a DependencyProperty as the backing store for LefMargin. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LefMarginProperty =
DependencyProperty.RegisterAttached("LefMargin", typeof(BindingExpression), typeof(Window1), new PropertyMetadata(null, new PropertyChangedCallback(MarginCallback)));
private static void MarginCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement elem = d as FrameworkElement;
BindingExpression exp = e.NewValue as BindingExpression;
// Create a new Binding to set ConverterParameter //
Binding b = new Binding();
b.Converter = exp.ParentBinding.Converter;
b.ConverterParameter = elem.Margin;
b.Path = exp.ParentBinding.Path;
b.ElementName = exp.ParentBinding.ElementName;
b.Mode = exp.ParentBinding.Mode;
elem.SetBinding(FrameworkElement.MarginProperty, b);
}
Converter
public class LeftMarginCnv : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double gridCtrlLeftMargin = ((Thickness)value).Left;
Thickness tgtCtrlMargin = (Thickness)parameter;
return new Thickness(gridCtrlLeftMargin, tgtCtrlMargin.Top, tgtCtrlMargin.Right, tgtCtrlMargin.Bottom);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Usage
<Grid>
<Grid Background="Red" Margin="29,55,52,125" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*"/>
<ColumnDefinition Width="121*"/>
</Grid.ColumnDefinitions>
<Button x:Name="Btn" Content="Press" Margin="18,22,35,28" Grid.Column="1" Click="Btn_Click"/>
</Grid>
<Button local:Window1.LefMargin="{Binding Margin, ElementName=Btn, Converter={StaticResource LeftMarginCnvKey}}" Content="Button" HorizontalAlignment="Left" Margin="55,199,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
Outer Button will change its Left Margin if you change the Left margin of inner Button.
You can set the common style for both. Something like this.
<StackPanel>
<StackPanel.Resources>
<Style x:Key="commonstyle" TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="10,0,0,0" />
</Style>
</StackPanel.Resources>
<TextBox x:Name="outside" Width="100" Height="70" Style="{StaticResource commonstyle}"/>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Width="100" Height="70" x:Name="inside" Grid.Column="2" HorizontalAlignment="Left" Style="{StaticResource commonstyle}"/>
</Grid>
</StackPanel>
(or)
Make it simple
<StackPanel>
<TextBox x:Name="outside" Width="100" Height="70" Margin="{Binding ElementName=inside, Path=Margin}"/>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Width="100" Height="70" x:Name="inside" Grid.Column="2" HorizontalAlignment="Left" Margin="20"/>
</Grid>
</StackPanel>
Hope that helps.

Custom attached property doesn't work like Canvas.Left [duplicate]

I have problem with creating xaml control. I'm writing new project in VS 2015 in universal app. I want create grid. In this grid I want to have a button. In model I specifi the column (Level) and Row.
this is my code:
<ItemsControl Grid.Row="1" ItemsSource="{Binding Path=TechnologyList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="Control">
<Setter Property="Grid.Column" Value="{Binding Level}" />
<Setter Property="Grid.Row" Value="{Binding Row}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I get a error in line <Setter Property="Grid.Column" Value="{Binding Level}" />
The error: Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED) was in edytor not in running code.
What is wrong? In "old" WPF everything was OK but in Universal App for Windows 10 I have a error.
Can anyone help me ?
As noted in the section Migration notes on the Setter.Value property page on MSDN, UWP/Windows Runtime does not support bindings in Style Setters.
Windows Presentation Foundation (WPF) and Microsoft Silverlight
supported the ability to use a Binding expression to supply the Value
for a Setter in a Style. The Windows Runtime doesn't support a Binding
usage for Setter.Value (the Binding won't evaluate and the Setter has
no effect, you won't get errors, but you won't get the desired result
either). When you convert XAML styles from WPF or Silverlight XAML,
replace any Binding expression usages with strings or objects that set
values, or refactor the values as shared {StaticResource} markup
extension values rather than Binding-obtained values.
A workaround could be a helper class with attached properties for the source paths of the bindings. It creates the bindings in code behind in a PropertyChangedCallback of the helper property:
public class BindingHelper
{
public static readonly DependencyProperty GridColumnBindingPathProperty =
DependencyProperty.RegisterAttached(
"GridColumnBindingPath", typeof(string), typeof(BindingHelper),
new PropertyMetadata(null, GridBindingPathPropertyChanged));
public static readonly DependencyProperty GridRowBindingPathProperty =
DependencyProperty.RegisterAttached(
"GridRowBindingPath", typeof(string), typeof(BindingHelper),
new PropertyMetadata(null, GridBindingPathPropertyChanged));
public static string GetGridColumnBindingPath(DependencyObject obj)
{
return (string)obj.GetValue(GridColumnBindingPathProperty);
}
public static void SetGridColumnBindingPath(DependencyObject obj, string value)
{
obj.SetValue(GridColumnBindingPathProperty, value);
}
public static string GetGridRowBindingPath(DependencyObject obj)
{
return (string)obj.GetValue(GridRowBindingPathProperty);
}
public static void SetGridRowBindingPath(DependencyObject obj, string value)
{
obj.SetValue(GridRowBindingPathProperty, value);
}
private static void GridBindingPathPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var propertyPath = e.NewValue as string;
if (propertyPath != null)
{
var gridProperty =
e.Property == GridColumnBindingPathProperty
? Grid.ColumnProperty
: Grid.RowProperty;
BindingOperations.SetBinding(
obj,
gridProperty,
new Binding { Path = new PropertyPath(propertyPath) });
}
}
}
You would use them in XAML like this:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="local:BindingHelper.GridColumnBindingPath" Value="Level"/>
<Setter Property="local:BindingHelper.GridRowBindingPath" Value="Row"/>
</Style>
</ItemsControl.ItemContainerStyle>
For a simple workaround for absolute positioning (i.e. binding the Canvas.Left and canvas.Top properties), see this answer.
Wanted to add my experience of this BindingHelper idea from #clemens. It's a neat solution but I found that when targetting a ListViewItem the binding wouldn't access the underlying view model. After debugging it, I found that I needed to make sure the binding was relative to the ListViewItem itself and the associated .Content property to enable it to correctly link to the item's view model.
My particular use case was to set the IsTabStop property of the ListViewItem based on a view model value:
private static void BindingPathPropertyChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is string propertyPath)
{
var binding = new Binding
{
Path = new PropertyPath($"Content.{propertyPath}"),
Mode = BindingMode.OneWay,
RelativeSource = new RelativeSource
{
Mode = RelativeSourceMode.Self
}
};
BindingOperations.SetBinding(obj, Control.IsTabStopProperty, binding);
}
}
Hope this helps if anyone else has the problem.

Specifying Grid column and row definition by style in resource

There is an UserControl with the following Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
</Grid>
Now I have a Window and there are I would to write something like that:
<Window.Resources>
<Style TargetType="Grid">
<Setter Property="RowDefinitions">
<Value>
<RowDefinition Height="*"/>
<RowDefinition/>
</Value>
</Setter>
</Style>
</Window.Resources>
The key part, which doesn't compile is when I want to change Height from Auto to *. How to do this in legal way?
In general I have to cases. 1) The first row should stretch and the second should be fixed. 2) Vice versa. Maybe a different panel than Grid could be more relevant?
Grid.RowDefinitions and Grid.ColumnDefinitions are no dependency properties, and can't hence be set by a Style.
You may perhaps create a dependency property FirstRowHeight in your UserControl, and bind the Height of the first RowDefinition to that property. Later you may set the FirstRowHeight property in a Style.
<Grid.RowDefinitions>
<RowDefinition Height="{Binding FirstRowHeight,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/>
<RowDefinition/>
</Grid.RowDefinitions>
The property would look like this:
public static readonly DependencyProperty FirstRowHeightProperty =
DependencyProperty.Register(
"FirstRowHeight", typeof(GridLength), typeof(YourUserControl));
public GridLength FirstRowHeight
{
get { return (GridLength)GetValue(FirstRowHeightProperty); }
set { SetValue(FirstRowHeightProperty, value); }
}
EDIT: In order to support the simple scenario you describe at the end of your question, you may also just have an IsFirstRowFixed dependency property with a property changed callback that sets the row heights in code:
<Grid.RowDefinitions>
<RowDefinition x:Name="row1" Height="*"/>
<RowDefinition x:Name="row2" Height="Auto"/>
</Grid.RowDefinitions>
The property:
public static readonly DependencyProperty IsFirstRowFixedProperty =
DependencyProperty.Register(
"IsFirstRowFixed", typeof(bool), typeof(UserControl2),
new PropertyMetadata((o, e) => ((UserControl2)o).IsFirstRowFixedChanged()));
public bool IsFirstRowFixed
{
get { return (bool)GetValue(IsFirstRowFixedProperty); }
set { SetValue(IsFirstRowFixedProperty, value); }
}
private void IsFirstRowFixedChanged()
{
if (IsFirstRowFixed)
{
row1.Height = GridLength.Auto;
row2.Height = new GridLength(1, GridUnitType.Star);
}
else
{
row1.Height = new GridLength(1, GridUnitType.Star);
row2.Height = GridLength.Auto;
}
}
XAML code :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Style="{StaticResource HeaderHeight}"</>
<Grid Grid.Row="1" Style="{StaticResource FooterHeight}"</>
</>
Styles in Resource dictionary
<Style TargetType="Frame" x:Name="HeaderHeight">
<Setter Property="Height" Value="700"></Setter>
</Style>
<Style TargetType="Grid" x:Name="FooterHeight">
<Setter Property="Height" Value="70"></Setter>
</Style>

How can I have only a * notation wpf grid column resize when the containing control is resized and not clip other columns?

I have a grid with certain column settings:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*" MinWidth="200"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="240" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="100*" />
</Grid.RowDefinitions>
....Omitting content to keep this simple....
</grid>
When I resize the width of the containing control, the center column resizes as expected, to a point. Then it will start to clip the third column for no apparent reason (there's still room for the center column to shrink). How can I force WPF to only resize the center column, and only clip the third column if the center column's width is at 0?
EDIT:
Try using a MultiValueConverter to minimize the MaxWidth of the second column to the available space in the grid. The code below should do the trick:
Xaml:
<Grid.ColumnDefinitions>
<ColumnDefinition Name="col1" Width=".25*" MinWidth="200"/>
<ColumnDefinition Name="col2" Width="*">
<ColumnDefinition.MaxWidth>
<MultiBinding Converter="{StaticResource GridWidthConverter}">
<Binding ElementName="col1" Path="MinWidth"/>
<Binding ElementName="col3" Path="Width"/>
<Binding ElementName="Control" Path="ActualWidth"/>
</MultiBinding>
</ColumnDefinition.MaxWidth>
</ColumnDefinition>
<ColumnDefinition Name="col3" Width="240" />
</Grid.ColumnDefinitions>
Converter:
public class GridWidthConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var col1 = System.Convert.ToDouble(values[0]);
var col2 = System.Convert.ToDouble(((GridLength)values[1]).Value);
var control = System.Convert.ToDouble(values[2]);
var maxWidth = control - (col1 + col2);
return maxWidth > 0 ? maxWidth : 0;
}
public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
#endregion
}
You may want to add some error checking to the converter but it should give you the idea.
I ended up figuring out the problem. Richard E led me in the right direction. Apparently the act of setting a * notation on a column and a minimum width caused the behavior I was experiencing. Specifically, when column 1 stopped shrinking due to hitting the minimum width, column 2 only continued to shrink at a rate that it would have if column 1 continued to shrink as well. This version of the xaml works correctly:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="240" />
</Grid.ColumnDefinitions>
I don't know if the behavior I encountered was intentional or not.
Thanks for the help!

Binding Items inside a DataTemplate with Items from another DataTemplate

I have two Data Template (one for drawing[draw] and another for Input Data[data]) Also I have the two ContentControls which uses the above DataTemplates.
I want the both DataTemplate's elements to be binded so that when the user fills in a field in the data form DateTemplate it automatically updates the draw Template as well.
How can I bind the elements in draw DataTemplate with the elements of data DataTemplate.
There is no backend data at all. User picks up a value from a combobox and based upon the value selected in combobox I update the two ContentControls with relevant draw and data DataTemplates. User fill in the relevant fields in the data form and draw template draws those elements based upon some business Rules.
-----
<DataTemplate x:Key="data">
<Grid Grid.Row="0" Background="#FFFFFFFF" Name="DocumentRoot" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Margin="10" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<TextBlock Text="Heading Text" Grid.Row="1"/>
<TextBlock Text="Ticket Text" Grid.Row="2"/>
-----
<TextBox x:Name="txtHeading" Text="Heading Text" Grid.Row="1" Grid.Column="1"/>
<TextBox x:Name="txtTicketText" Text="Ticket Text" Grid.Row="2" Grid.Column="1"/>
-----
</Grid>
</Grid>
</DataTemplate>
<ContentControl Content="{Binding ElementName=cboTemplates, Path=SelectedItem.Name}"
ContentTemplateSelector="{StaticResource formTemplateSelector}">
</ContentControl>
Any ideas how can I bind the two elements from inside different DataTemplates?
Thanks in advance
Consider creating class (named View Model) and bind both templates to single instance of that class (this is Model-View-ViewModel design pattern). Otherwise you probably will have very complex bindings contains hardcoded logical tree.
Why don't you bind one object (of class with a Draw property and a Data property) to both the templates. When one template changes Data property in the object, you can refresh Draw property in the object which in turn will update the Draw template.
Updated
Example :
Window Content
<Grid>
<StackPanel>
<ContentControl DataContext="{Binding}">
<ContentControl.Template>
<ControlTemplate>
<Rectangle Fill="{Binding Background}"
Width="200"
Height="200" />
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
<ContentControl DataContext="{Binding}">
<ContentControl.Template>
<ControlTemplate>
<TextBox Text="{Binding ColorText}" />
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</StackPanel>
</Grid>
Code Behind
public partial class MultiViewWindow : Window
{
public MultiViewWindow()
{
InitializeComponent();
DataContext = new BackgroundInfo();
}
}
public class BackgroundInfo : INotifyPropertyChanged
{
protected String _colorText;
public String ColorText
{
get
{
return _colorText;
}
set
{
_colorText = value;
RaisePropertyChanged("ColorText");
RaisePropertyChanged("Background");
}
}
public Brush Background
{
get
{
try
{
return new SolidColorBrush((Color)ColorConverter.ConvertFromString(ColorText));
}
catch (Exception)
{
return new SolidColorBrush(Colors.Transparent);
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(String propertyName)
{
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Resources