Graphics from ScrollViewer overlays graphics outside ScrollViewer when scrolled down (WPF) - wpf

I have a XAML file. In this XAML file I have a ScrollViewer to which later I add WinFormsHost -> basically place where you can put standard WinForm. When I scroll the ScrollViewer down the graphics from inside of it goes outside. Please look at the first an the second screenshot. How to deal with that drawing problem? Can I set ZIndex for that ScrollViewer?
<Window x:Class="Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Example"
Title="MainWindow" WindowState="Maximized" Loaded="Window_Loaded"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="3*" />
<RowDefinition Height="7*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <!-- this column is for future purpouses -->
<ColumnDefinition Width="1366" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="Red" BorderThickness="4" Grid.Column="0" Grid.Row="0">
<ListBox x:Name="ListBox"
</ListBox>
</Border>
<Button x:Name="AcceptButton" Grid.Row="1" ></Button>
</Grid>
<Border BorderBrush="Green" BorderThickness="2" Grid.Column="1" Grid.Row="2">
<ScrollViewer Grid.Column="1" Grid.Row="2" >
<WrapPanel x:Name="WinFormsPanel" Grid.Column="1" Grid.Row="2">
</WrapPanel>
</ScrollViewer>
</Border>
</Grid>
</Window>
AT THE BEGINNING
SCROLLED DOWN - WHEN SCROLLED UP EVERYTHING GOES BACK TO NORMAL
**EDIT ** Tried, but no difference:
<Border BorderBrush="Green" BorderThickness="2" Grid.Column="1" Grid.Row="2" ClipToBounds="True">
<ScrollViewer ClipToBounds="True" Grid.Column="1" Grid.Row="2" >
<WrapPanel ClipToBounds="True" x:Name="VideoPanel" Grid.Column="1" Grid.Row="2">
</WrapPanel>
</ScrollViewer>
</Border>
EDIT 2:
XAML
<Window x:Class="HomeSecurity.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HomeSecurity"
Title="MainWindow" WindowState="Maximized" Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="9*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="8*" />
</Grid.ColumnDefinitions>
<Border BorderBrush="Green" BorderThickness="2" Grid.Column="1" Grid.Row="2">
<ScrollViewer >
<WrapPanel x:Name="VideoPanel" >
</WrapPanel>
</ScrollViewer>
</Border>
<Button Content="Button" Grid.Column="1" HorizontalAlignment="Left" Margin="23,30,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
MAINWINDOW.XAML.CS
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.Forms.Integration;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HomeSecurity {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
add(); add(); add();
}
private void add() {
WindowsFormsHost formsHost = new WindowsFormsHost();
VideoStream videoStream = new VideoStream();
formsHost.Width = 400;
formsHost.Height = 400;
formsHost.Child = videoStream;
Border lineBorder = new Border();
lineBorder.BorderBrush = Brushes.Green;
lineBorder.BorderThickness = new Thickness(2);
lineBorder.Child = formsHost;
VideoPanel.Children.Add(lineBorder);
}
}
}
There has to be added reference to System.WindowsFormsIntegration, System.Windows.Forms, System.Drawing.

You clearly have some problem there and you should thoroughly investigate what is going on with your code to try to rectify the situation optimally. However, the code that you have shown here is not to blame. I tried it in a new project and it works as expected. As there is nothing inside the WrapPanel, there is no content in the ScrollViewer to cause your problem. When adding code to demonstrate a problem, you should ensure that your code does demonstrate the problem.
Even so, without being able to recreate your problem, there might just be a quick fix that you can use in this case. You can just set the UIElement.ClipToBounds property on the Border to True and this will clip anything that extends beyond its bounds.
<Border ClipToBounds="True" BorderBrush="Green" BorderThickness="2" ...>
<ScrollViewer Grid.Column="1" Grid.Row="2" >
<WrapPanel x:Name="WinFormsPanel" Grid.Column="1" Grid.Row="2">
</WrapPanel>
</ScrollViewer>
</Border>

Related

WPF UserControl: Open another UserControl (Popup) when click on UserControl object

I have built a button wrapper around the User Control (FFU), so the object is clickable trough the main window. When the FFU object is clicked, I want to open another User Control: Popup FFU to be opened.
Main window XAML
<vw:BaseWindow
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vw="http://inosoft.com/visiwin7"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:UserControls="clr-namespace:HMI.Windows.UserControls" x:Class="HMI.MainWindow"
mc:Ignorable="d"
ResizeMode="NoResize"
WindowStyle="None" WindowState="Normal" WindowStartupLocation="CenterScreen"
Width="1024" Height="768">
<Grid x:Name="LayoutRoot" UseLayoutRounding="True">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<vw:Region x:Name="MainRegion" StartView="MainView1" DesignTimeView="MainView1" Grid.Row="0" Margin="0,96,0,4" Grid.RowSpan="2" />
<vw:Region x:Name="HeaderRegion" StartView="HeaderView" DesignTimeView="HeaderView" Grid.Row="0" />
<vw:Region x:Name="FooterRegion" StartView="FooterView" DesignTimeView="FooterView" Grid.Row="2" />
<UserControls:UC_FFU x:Name="FFU_1" HorizontalAlignment="Left" Height="28" Margin="305,85,0,0" Grid.Row="1" VerticalAlignment="Top" Width="44"/>
<UserControls:UC_FFU x:Name="FFU_2" HorizontalAlignment="Left" Height="29" Margin="358,85,0,0" Grid.Row="1" VerticalAlignment="Top" Width="44"/>
<UserControls:UC_FFU x:Name="FFU_3" HorizontalAlignment="Left" Height="29" Margin="410,85,0,0" Grid.Row="1" VerticalAlignment="Top" Width="44" StateBrush="{vw:VariableBinding VariableName=MCS1.Cleanroom.SIM_Cleanroom.SIM_FFUControl1.Observers.oStatus, Converter={StaticResource ValueToStateBrushConverter}, States={StaticResource BrushListStatus}, StateMode=Value}" PopupFFUInstance="{Binding MyDataContextPopupFFUProperty}"/>
</Grid>
</vw:BaseWindow>
UserControl code XAML
<UserControl x:Class="HMI.Windows.UserControls.UC_FFU"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HMI.Windows.UserControls"
mc:Ignorable="d"
x:Name="_this" d:DesignWidth="42" Height="27.544">
<Button x:Name="Btn" IsHitTestVisible="{Binding ElementName=Popup, Path=IsOpen, Mode=OneWay}" Click="Btn_Click">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="19*"/>
<ColumnDefinition Width="8*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="{Binding ElementName=_this, Path=StateBrush}" Width="40" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1,1,0,0" Grid.ColumnSpan="6"/>
<Line Stroke="#FF000000" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1,1,0,0" Width="0" Y1="0" Y2="24" X1 ="-.5" X2="-.5"/>
<Line Stroke="#FF000000" Width="40" HorizontalAlignment="Left" VerticalAlignment="Top" Margin=".5,25,-2,0" Width="43" Y1="0" Y2="0.114682539682633" X2="40.5" Grid.ColumnSpan="6"/>
<Line Stroke="#FF000000" Height="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1,1,-2,0" Width="43" Y1="0" Y2="0.114682539682633" X2="39.5" Grid.ColumnSpan="6"/>
</Grid>
<Button.Template>
<ControlTemplate x:Name="BlankButtonTemplate" TargetType="{x:Type ButtonBase}">
<Border Background="#00000000">
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</UserControl>
UserControl FFU backhand
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
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 HMI.Windows.UserControls
{
/// <summary>
/// Interaction logic for UC_FFU.xaml
/// </summary>
public partial class UC_FFU : UserControl
{
//Create PopupFFUProperty
public static readonly DependencyProperty PopupFFUProperty =
DependencyProperty.Register("PopupFFUInstance", typeof(int), typeof(UC_FFU));
public int PopupFFUInstance
{
get { return (int)GetValue(PopupFFUProperty); }
set { SetValue(PopupFFUProperty, value); }
}
public UC_FFU()
{
InitializeComponent();
}
//Added the Click Event
public event RoutedEventHandler Click
{
add { Btn.AddHandler(ButtonBase.ClickEvent, value); }
remove { Btn.AddHandler(ButtonBase.ClickEvent, value); }
}
private void Btn_Click(object sender, RoutedEventArgs e)
{
// Something to open the UserControl FFU Popup....
}
}
}
Simple Pop up example FFU XAML
<UserControl x:Class="HMI.Windows.UserControls.PopupControl.Popup_FFU"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HMI.Windows.UserControls.PopupControl"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<Popup IsOpen="{Binding IsChecked, ElementName=button}" StaysOpen="False">
<Border Background="LightYellow">
<TextBlock>I'm the popup</TextBlock>
</Border>
</Popup>
</UserControl>
How can this be achieved?
I have tried to open a new window like this: however it should be a popup. Not a dialog window.
Window window = new Window
{
Title = "My User Control Dialog",
Content = new PopupControl.Popup_FFU()
};
window.Show();
This is what I would change in your code.
UC_FFU.xaml: Put this before your closing </Grid>
<Popup x:Name="ButtonPopup" StaysOpen="False">
<UserControls:Popup_FFU />
</Popup>
UC_FFU.xaml.cs:
private void Btn_Click(object sender, RoutedEventArgs e)
{
ButtonPopup.IsOpen = true;
}
Popup_FFU.xaml:
<UserControl x:Class="HMI.Windows.UserControls.PopupControl.Popup_FFU"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HMI.Windows.UserControls.PopupControl"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<Border Background="LightYellow">
<TextBlock>I'm the popup</TextBlock>
</Border>
</UserControl>

Negative-margin control get clipped when resizing the window in WPF

I try to understand why a border element get clipped when reducing the width of the main window.
Please take a look the code block below.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="500" Name="MainWin">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Background="Blue" Grid.Row="0" BorderBrush="Black" Width="{Binding ElementName=MainWin, Path=Width}" />
<Grid Grid.Row="1" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Background="Black">
<Border Background="White" Width="150" Height="150" BorderBrush="Black" BorderThickness="2"
Margin="0,-100,0,0">
<TextBlock Text="{Binding ElementName=MainWin, Path=Width}" FontSize="14" FontWeight="Bold"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</StackPanel>
<StackPanel Grid.Column="1" Background="Red" />
<StackPanel Grid.Column="2" Background="Yellow" />
</Grid>
</Grid>
</Window>
Here is what the border appears in the original window width:
Non-resized window
As you can see that the border is displayed outside its container because of the negative top margin, -100 in this case. This is what I expect to have for the border. But when I reduce the main window width to reach the right edge of the red rectangle the outside part of the border get clipped.
Resized window
I have tried to place this border element inside a custom StackPanel which overrides ArrangeOverride, MeasureOverride and GetLayoutClip method but unfortunately these methods are not invoked when the main window is being resized.
I appreciate if somebody can explain me what the reason is and how to work around with this issue.
Thanks a lot.
Based on the explanation of #Marks, here is my solution
Create a custom grid and overrides MeasureOverride method
Replace the inner grid by this custom grid
CustomGrid class
public class CustomGrid : Grid
{
private double _originalHeight = 0;
protected override Size MeasureOverride(Size constraint)
{
Size? size = null;
if (constraint.Width <= 300)
{
size = new Size(constraint.Width, _originalHeight);
}
else
{
size = base.MeasureOverride(constraint);
_originalHeight = constraint.Height;
}
return size.Value;
}
}
XAML code
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="300" Width="500" Name="MainWin">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Background="Blue" Grid.Row="0" BorderBrush="Black" Width="{Binding ElementName=MainWin, Path=Width}" />
<wpfApplication1:CustomGrid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Background="Black">
<Border Background="White" Width="150" Height="150" BorderBrush="Black" BorderThickness="2"
Margin="0,-100,0,0">
<TextBlock Text="{Binding ElementName=MainWin, Path=Width}" FontSize="14" FontWeight="Bold"
HorizontalAlignment="Center"
VerticalAlignment="Bottom" />
</Border>
</StackPanel>
<StackPanel Grid.Column="1" Background="Red" />
<StackPanel Grid.Column="2" Background="Yellow" />
</wpfApplication1:CustomGrid>
</Grid>
You're binding the blue border's Width to the MainWindow's Width.
For the future: if you want to bind to the width of any FrameworkElement bind to its ActualWidth property.
The order in which WPF draws its stuff is quite dependent on the containing control. I'd say in your case the outer Grid draws its children that need updating in the order they are defined. So you're good to go as long as the inner grid changes along with the border. This is the case as long as the Width of the third column changes. Once it's at 0 there's no more change so it doesn't get updated.
(2) is speculation =)
don't do (1), there's no need for it
Use one Grid
Some XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Background="Blue" BorderBrush="Black" Grid.ColumnSpan="3"/>
<StackPanel Grid.Column="0" Grid.Row="1" Background="Black" >
<Border Background="White" Width="150" Height="150" BorderBrush="Black" BorderThickness="2" Margin="0,-100,0,0">
<TextBlock Text="{Binding ElementName=MainWin, Path=ActualWidth}" FontSize="14" FontWeight="Bold"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="1" Background="Red" />
<StackPanel Grid.Column="2" Grid.Row="1" Background="Yellow" />
</Grid>

I can't get my WebBrowser and Textbox to display when I execute the app. I can see them in my design window.

Here is my XAML and C# code along with it. I'm pretty new to xaml so have some grace towards me. Like I mentioned above I simply cant see the WebBrowser window or the TextBox when I execute the app.
XAML:
<Window x:Class="HTML_Viewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="HTML Viewer" Height="350" Width="525">
<Grid Name="grid_Main">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Menu Background="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Row="0">
<MenuItem Header="File">
<MenuItem Header="Open HTML File"/>
<Separator/>
<MenuItem Header="Save"/>
<Separator/>
</MenuItem>
<ToolBar Width="Auto">
<Button x:Name="btnLocal" BorderBrush="DarkGray" Content="Load Local" Click="btnLocal_Click" Width="67"
HorizontalAlignment="Center" VerticalAlignment="Center" Cursor="Hand" Panel.ZIndex="1"
Margin="0,0,0,-1" Height="22"/>
<Button x:Name="btnCodeView" BorderBrush="DarkGray" Content="Code View" Click="btnCodeView_Click" Width="67"
HorizontalAlignment="Center" VerticalAlignment="Center" Cursor="Hand" Panel.ZIndex="1"
Height="Auto" Margin="0,0,0,-1"/>
<Button x:Name="btnPageView" BorderBrush="DarkGray" Content="Page View" Click="btnPageView_Click" Width="67"
HorizontalAlignment="Center" VerticalAlignment="Center" Cursor="Hand" Panel.ZIndex="1"
Height="Auto" Margin="0,0,0,-1"/>
<Button x:Name="btnSplitView" BorderBrush="DarkGray" Content="Split View" Click="btnSplitView_Click" Width="67"
HorizontalAlignment="Center" VerticalAlignment="Center" Cursor="Hand" Panel.ZIndex="1"
Height="Auto" Margin="0,0,0,-1"/>
</ToolBar>
</Menu>
<Grid Name="innerGrid" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Name="col1" Width="*"/>
<ColumnDefinition Name="col2" Width="*"/>
</Grid.ColumnDefinitions>
<WebBrowser x:Name="webOutput" Width="{Binding ElementName=col1,Path=ActualWidth}"
Height="{Binding ElementName=col1, Path=ActualHeight}"/>
<TextBox x:Name="txtInput" Background="Bisque" Grid.Column="1" Width="{Binding ElementName=col2,Path=ActualWidth}"
Height="{Binding ElementName=col2, Path=ActualHeight}" />
</Grid>
</Grid>
</Window>
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using Microsoft.Win32;
using System.IO;
namespace HTML_Viewer
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnCodeView_Click(object sender, RoutedEventArgs e)
{
}
private void btnLocal_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
webOutput.Navigate(new Uri(openFileDialog.FileName));
txtInput.Text = File.ReadAllText(openFileDialog.FileName);
}
}
private void btnPageView_Click(object sender, RoutedEventArgs e)
{
}
private void btnSplitView_Click(object sender, RoutedEventArgs e)
{
}
}
}
I am able to view your Controls by removing Height and width given to that,
<WebBrowser x:Name="webOutput" />
<TextBox x:Name="txtInput" Background="Bisque" Grid.Column="1"/>

How to use content of derived controls in silverlight

In my project lots of views must have Ok,Cancel button to bottom of view. So i want create a base control. And add Ok, Cancel button to bottom of this control. Then i will inherite this control. In the inherited control i want to ad a textbox to near this buttons. How can i do this?
I believe there is a template for the base control.Is so in the inherited control's template edit the button panel and add textbox.
You can create Control which is inherited from ContentControl and define your buttons in ControlTemplate of it. Then you can just use this control as shown in sample.
ControlWithButtons.cs
[TemplatePart(Name="btnOk", Type= typeof(Button))]
public class ControlWithButtons : ContentControl
{
public ControlWithButtons()
{
this.DefaultStyleKey = typeof(ControlWithButtons);
}
Button _btnOk;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_btnOk = GetTemplateChild("btnOk") as Button;
if (_btnOk != null)
{
// do what you want with you button
_btnOk.Click += new RoutedEventHandler(_btnOk_Click);
}
}
void _btnOk_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Ok button clicked");
}
}
Generic.xaml (must be in (ProjectDir)/Themes/Generic.xaml)
(do not forget xmlns:local="clr-namespace:Test")
<Style TargetType="local:ControlWithButtons">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ControlWithButtons">
<Border Background="Yellow" CornerRadius="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Border Margin="10" Background="LightGray">
<ContentPresenter/>
</Border>
<Button Grid.Row="1" x:Name="btnOk" Content="OK" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Using your control:
<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<local:ControlWithButtons Width="300" Height="250" HorizontalAlignment="Center" VerticalAlignment="Center">
<!-- TextBox is put into control -->
<TextBox Width="200" Height="Auto" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5" />
<!-- You can also specify ContentTemplate for ControlWithButtons -->
<!-- (see in MSDN "http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.contenttemplate(v=vs.95).aspx") -->
</local:ControlWithButtons>
</Grid>
I found the solution. [ContentProperty("")] attribute solved my problem.
Like this:
Base Xaml
<Grid Name="layoutRoot" VerticalAlignment="Stretch" >
<Grid.RowDefinitions>
<RowDefinition Height="289*" />
<RowDefinition Height="51" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Orientation="Horizontal">
<Button Name="btnOk" Content="Ok" Height="23" Width="75" HorizontalAlignment="Left" Margin="10,10,10,10" Command="{Binding Path=OnApply, Mode=OneWay}"/>
<Button Name="btnCancel" Content="Cancel" Height="23" Width="75" HorizontalAlignment="Left" Margin="10,10,10,10"/>
</StackPanel>
<Grid Name="rootContent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="0" Grid.Row="0" />
</Grid>
</sdk:ChildWindow>
Base CodeBehind
[ContentProperty("RootContentControl")]//This attribute solved my problem.
public partial class BaseView : ChildWindow
{
public BaseView()
{
InitializeComponent();
}
public UIElementCollection RootContentControl
{
get { return rootContent.Children; }
}
}
Inherited Xaml
<Views:BaseView x:Class="MvvmLight1.Views.InheritedView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Views="clr-namespace:MvvmLight1.Views"
xmlns:viewModels="clr-namespace:MvvmLight1.ViewModel"
mc:Ignorable="d" d:DesignHeight="244" d:DesignWidth="392"
DataContext="{Binding Source=viewModels:InheritedViewModel}">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
</Views:BaseView>
Inherited CodeBehind
public partial class InheritedView : BaseView
{
public InheritedView()
{
InitializeComponent();
}
}

XAML ScrollViewer scroll bar hidden issue (Silverlight)

I’ve got this strange problem whereby the content within a scroll viewer increases in size, the scroll viewer then shows is horizontal scroll bar. However the grid the ScrollViewer is ultimately within doesn’t seem to resize enough to show the scroll bar.
I’ve isolated the problem in this sample app, basically some xaml and some code behind to simulate the content size increase.
Note how the right scroll bar is not correctly showing when you click the resize button, I’ve added some padding to show that its there but not in the correct place.
If I remove the top row it seems to work.
Any ideas and thanks in advance guys and girls?
<UserControl x:Class="SilverlightApplication7.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Grid
ShowGridLines="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
>
<Grid.RowDefinitions>
<RowDefinition x:Name="DealHeaderRow" Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="DealBarColumn" Width="Auto"></ColumnDefinition>
<ColumnDefinition x:Name="MarketViewerColumn" Width="Auto"></ColumnDefinition>
<ColumnDefinition x:Name="DealEditorColumn" Width="*" ></ColumnDefinition>
<ColumnDefinition x:Name="InfoColumn" Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ContentControl
x:Name="DealBarRegionContentControl"
Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="2"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="0">
<TextBlock Text="DealBarRegion" Width="150" />
</ContentControl>
<ContentControl
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<Border Background="#FF9AF172">
<TextBlock Text="MarketViewerRegion" Width="150" />
</Border>
</ContentControl>
<ContentControl
Grid.Column="2"
Grid.ColumnSpan="2"
Grid.Row="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch" >
<Border Background="#FFC1FC9F">
<TextBlock Text="DealHeaderRegion" />
</Border>
</ContentControl>
<ContentControl
Grid.Column="2"
Grid.Row="1"
VerticalAlignment="Top"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<Border Background="MistyRose" >
<TextBlock Text="DealEditorRegion" />
</Border>
</ContentControl>
<Grid
Grid.Column="3"
Grid.Row="1"
>
<ContentControl
x:Name="InfoRegionControl"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Stretch">
<!-- without the padding here you can't see the scroll bar at all !! Its like the
scroll ScrollViewer isn't correctly calculating its width to include the scroll bar,
or the grid isn't sizing at the points its visible??-->
<Border Padding="0,0,9,0" MinWidth="200" x:Name="DealInfoControlPlaceHolder">
<ScrollViewer
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
>
<StackPanel x:Name="ScrollContentPlaceHolder">
<Button Click="Button_Click" Content="Rezize Column" x:Name="ResizeButton" />
</StackPanel>
</ScrollViewer>
</Border>
</ContentControl>
</Grid>
</Grid>
And here is the code behind:
using System.Windows;
using System.Windows.Controls;
namespace SilverlightApplication7
{
public partial class MainPage : UserControl
{
double _dealInfoControlPlaceHolderHeight = 0;
double _dealInfoControlPlaceHolderWidth = 0;
public MainPage()
{
InitializeComponent();
Loaded += (o, e) =>
{
// cache the original width and height
_dealInfoControlPlaceHolderHeight = DealInfoControlPlaceHolder.Height;
_dealInfoControlPlaceHolderWidth = DealInfoControlPlaceHolder.Width;
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (ScrollContentPlaceHolder.Height == 1200)
{
ScrollContentPlaceHolder.Height = _dealInfoControlPlaceHolderHeight;
ScrollContentPlaceHolder.Width = _dealInfoControlPlaceHolderWidth;
}
else
{
ScrollContentPlaceHolder.Height = 1200;
ScrollContentPlaceHolder.Width = 250;
}
}
}
}
Ok I don’t know why the above doesn’t work, but as a workaround I just restructure the page so its behaves the same. That works:
<UserControl x:Class="SilverlightApplication7.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Grid
ShowGridLines="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="DealBarColumn" Width="Auto"></ColumnDefinition>
<ColumnDefinition x:Name="MarketViewerColumn" Width="Auto"></ColumnDefinition>
<ColumnDefinition x:Name="DealEditorColumn" Width="*" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<ContentControl
x:Name="DealBarRegionContentControl"
Grid.Column="0"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="0">
<TextBlock Text="DealBarRegion" Width="150" />
</ContentControl>
<ContentControl
Grid.Column="1"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<Border Background="#FF9AF172">
<TextBlock Text="MarketViewerRegion" Width="150" />
</Border>
</ContentControl>
<Grid
Grid.Column="2" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl
Grid.Row="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch" >
<Border Background="#FFC1FC9F">
<TextBlock Text="DealHeaderRegion" />
</Border>
</ContentControl>
<Grid
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ContentControl
Grid.Column="0"
VerticalAlignment="Top"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<Border Background="MistyRose" >
<TextBlock Text="DealEditorRegion" />
</Border>
</ContentControl>
<ContentControl
Grid.Column="1"
x:Name="InfoRegionControl"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Right">
<!-- without the padding here you can't see the scroll bar at all !! Its like the
scroll ScrollViewer isn't correctly calculating its width to include the scroll bar,
or the grid isn't sizing at the points its visible??-->
<Border Padding="0,0,9,0" MinWidth="200" x:Name="DealInfoControlPlaceHolder">
<ScrollViewer
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
>
<StackPanel x:Name="ScrollContentPlaceHolder">
<Button Click="Button_Click" Content="Rezize Column" x:Name="ResizeButton" />
</StackPanel>
</ScrollViewer>
</Border>
</ContentControl>
</Grid>
</Grid>
</Grid>

Resources