Creating a simple seeking media player with MediaElement in WPF - c#

I have also posted this on MSDN forums - i hope its not a problem.
I am basically trying to create a WPF based video player which allows you to seek within media. I'm trying to implement it using MediaTimeline (i know i can change the Position property, but i had other issues which i'll post in a separate question). XAML and code-behind are below.
Thanks for looking...
MainWindow.xaml
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<MediaElement x:Name="mediaElement" Width="320" Height="240" Margin="4" LoadedBehavior="Manual"/>
<Slider x:Name="slider" Grid.Row="1" Margin="4"/>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace WpfApplication5
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var tl = new MediaTimeline(new Uri(#"c:\temp\!numa.wmv"));
mediaElement.Clock = tl.CreateClock(true) as MediaClock;
mediaElement.MediaOpened += (o, e) =>
{
slider.Maximum = mediaElement.NaturalDuration.TimeSpan.Seconds;
mediaElement.Clock.Controller.Pause();
};
slider.ValueChanged += (o, e) =>
{
mediaElement.Clock.Controller.Seek(TimeSpan.FromSeconds(slider.Value), TimeSeekOrigin.BeginTime);
};
}
}
}

You need to set ScrubbingEnabled="True" on MediaElement to have it update during seeks.

the MediaOpened event should actually be setting the maximum value to .TotalSeconds, and you should also set ScrubbingEnabled to True as jesperll pointed out.

Related

How to get C# WPF MVVM Screensaver use dual monitor?

I am looking for an answer howto get a C#-WPF-MVVM-Screensaver-View on dual and more monitors running. I read several tutorials on webpages and answers here. However, never the coding samples worked on wpf.
Have someone a code exmple that works for wpf and Model View ViewModel Pattern?
I appreciate your help and thank you.
Thanks. I did it on Windows 10.
Create new WPF Window project for C#
Remove the startupuri / startuplocation from app.xaml.
Add a startup method to app.xaml.
4.
<Application x:Class="SeveralDisplays.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SeveralDisplays"
Startup="OnStartup">
<Application.Resources>
</Application.Resources>
</Application>
using System.Drawing;
using System.Windows;
using System.Windows.Forms;
using Application = System.Windows.Application;
namespace SeveralDisplays
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void OnStartup(object sender, StartupEventArgs e)
{
Window mainWindow1 = new MainWindow();
Window mainWindow2 = new MainWindow2();
Screen s1 = Screen.AllScreens[0];
Screen s2 = Screen.AllScreens[1];
Rectangle r1 = s1.WorkingArea;
Rectangle r2 = s2.WorkingArea;
mainWindow1.Top = r1.Top;
mainWindow1.Left = r1.Left;
mainWindow2.Top = r2.Top;
mainWindow2.Left = r2.Left;
mainWindow1.Show();
mainWindow2.Show();
mainWindow2.Owner = mainWindow1;
}
}
}
add two classes and ensure they are window-classes.
First / Main view, do not change here too much
<Window x:Class="SeveralDisplays.MainWindow"
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:local="clr-namespace:SeveralDisplays"
mc:Ignorable="d"
Loaded="MainWindow_OnLoaded"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>
first window code behind
using System.Windows;
namespace SeveralDisplays
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Maximized;
WindowStyle = WindowStyle.None;
ShowInTaskbar = false;
}
}
}
Second xaml as window
<Window x:Class="SeveralDisplays.MainWindow2"
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:local="clr-namespace:SeveralDisplays"
mc:Ignorable="d"
Title="MainWindow2"
WindowStartupLocation="Manual"
WindowStyle="None"
WindowState="Maximized"
Height="300" Width="300">
<Grid>
</Grid>
</Window>
Code behind:
using System.Windows;
namespace SeveralDisplays
{
public partial class MainWindow2 : Window
{
public MainWindow2()
{
InitializeComponent();
}
}
}
you can do this simplified and smart. I use only a method inside app.xaml.cs
/// <summary>
/// Shows the screensaver on every monitor. This is a multi monitor
/// application.
/// </summary>
private void ShowScreenSaver()
{
ClockWindow ownerWindow = null;
// Creates window on other screens.
foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens)
{
ClockWindow window = new ClockWindow(screen.Bounds.Width,
screen.Bounds.Height);
// Primary screen does not have WindowsStartupLocation.
if (screen.Primary)
{
// Maximizes screen.
window.WindowState = WindowState.Maximized;
ownerWindow = window;
}
else
{
// Other screens need a WindowStartupLocation on manual.
window.WindowStartupLocation = WindowStartupLocation.Manual;
System.Drawing.Rectangle location = screen.Bounds;
window.Top = location.Top;
window.Left = location.Left - 480;
window.Width = location.Width;
window.Height = location.Height;
}
window.Show();
}
// Sets every other screen owned to prmary window.
// It closes all windows at once.
foreach (Window window in Current.Windows)
{
if (window != ownerWindow)
{
window.Owner = ownerWindow;
}
}
}
Here I added a View, which I initializes for several displays.
<Window x:Class="Clock_ScreenSaver.Views.ClockWindow"
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:local="clr-namespace:Clock_ScreenSaver.Views"
mc:Ignorable="d"
Title="ClockWindow"
Height="{Binding DisplayHeight}"
Width="{Binding DisplayWidth}"
AllowsTransparency="True"
Background="Black"
Cursor="None"
ShowInTaskbar="False"
KeyDown="ClockWindow_KeyDown"
MouseMove="ClockWindow_MouseMove"
MouseDown="ClockWindow_MouseDown"
Closing="ClockWindowClosing"
Loaded="ClockWindowLoaded"
WindowStyle="None"
ResizeMode="NoResize">
<Grid Name="WindowGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Row="1" Grid.Column="1" CornerRadius="360" BorderBrush="#FFDF66" BorderThickness="5" Background="#2D2D30">
<StackPanel>
<Label Foreground="#FFDF66" Margin="0,15,0,0" FontSize="25" FontFamily="Arial" HorizontalAlignment="Center">DIGICLOCK</Label>
<StackPanel Background="#3F3F46" Margin="0,20,0,5" Width="280" Height="100">
<Label Content="{Binding ClockTime}" Name="timelbl" Margin="0,20,0,0" Foreground="#FFDF66" FontSize="40" FontFamily="Arial" HorizontalAlignment="Center"></Label>
</StackPanel>
<StackPanel Background="#3F3F46" Margin="0,0,0,10" Width="280" Height="50">
<Label Content="{Binding ClockDate}" Name="datelbl" Margin="0,8,0,0" Foreground="#FFDF66" FontSize="20" FontFamily="Arial" HorizontalAlignment="Center"></Label>
</StackPanel>
<Button Width="60" Padding="5,5,5,5" Background="#FFDF66" FontSize="10" FontFamily="Arial" Foreground="#333333" BorderThickness="0" Name="QuitBtn" Click="QuitBtn_Click">
Quit
</Button>
</StackPanel>
</Border>
</Grid>
</Window>

pull down to refresh listbox in windows phone 8.1 Silverlight

I am new in windows phone development. i want to try to implement pull down to refresh page. i use listbox under scrollviewer i am having a problem while implement in windows phone 8.1 silverlight application. here is my code
MainPage.xaml
<phone:PhoneApplicationPage
x:Class="PullDownToScroll.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid>
<ScrollViewer Name="OuterScroll" Loaded="OuterScroll_Loaded" LayoutUpdated="OuterScroll_ViewChanged">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Background="GreenYellow">
<Image Source="Assets/down13.png" Height="40" Width="40" HorizontalAlignment="Left" Margin="20,0,0,0">
<Image.RenderTransform>
<RotateTransform x:Name="RefreshIndicatiorRotateTransform" CenterX="20" CenterY="20"/>
</Image.RenderTransform>
</Image>
<TextBlock Name="RefreshIndicatiorTextBlock" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="80,0,0,0" Width="200" Foreground="Black"/>
</Grid>
<ListBox Name="InnerListView" Grid.Row="1">
</ListBox>
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PullDownToScroll.Resources;
using System.Windows.Media;
namespace PullDownToScroll
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.InitializeComponent();
InnerListView.Height = ApplicationView.GetForCurrentView().VisibleBounds.Height;
GenerateRandomListViewItem();
this.NavigationCacheMode = NavigationCacheMode.Required;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
public void GenerateRandomListViewItem()
{
InnerListView.Items.Clear();
Random rand = new Random();
for (int i = 0; i < 20; i++)
{
ListBox item = new ListBox();
item.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(0, 255), (byte)rand.Next(0, 255), (byte)rand.Next(0, 255)));
item.Height = rand.NextDouble() * 150;
item.Margin = new Thickness(0, 8, 0, 8);
InnerListView.Items.Add(item);
}
}
private void OuterScroll_Loaded(object sender, RoutedEventArgs e)
{
OuterScroll.ChangeView(null, 60, null, false);
}
private void OuterScroll_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (!e.IsIntermediate)
{
if (OuterScroll.VerticalOffset < 60)
{
if (OuterScroll.VerticalOffset <= 0.5)
OuterScroll.ChangeView(null, 60, null, false);
else
OuterScroll.ChangeView(null, 60, null);
}
if (OuterScroll.VerticalOffset <= 0.5)
{
GenerateRandomListViewItem();
}
}
else
{
double angle = (65 - OuterScroll.VerticalOffset) * 180 / 65;
RefreshIndicatiorRotateTransform.Angle = angle;
}
if (OuterScroll.VerticalOffset == 0)
RefreshIndicatiorTextBlock.Text = "Release to refresh";
else
RefreshIndicatiorTextBlock.Text = "Pull to refresh";
}
}
}
In MainPage.xaml.cs i found an error
Error 1 The type or namespace name 'ScrollViewerViewChangedEventArgs' could not be found (are you missing a using directive or an assembly reference?)
how should i resolve this problem ?? please share you suggestion.
Thanks in advance.
Best way to refresh view/screen use Application bar. Put refresh icon in Application bar and on icon click refresh your view/screen.
This link is help full for how to use Appication bar

Silverlight ComboBox value does not fall within the expected range

We are developing a silverlight 5 application. Within our application we use the combobox control.
When a combobox is open (IsDropDownOpen = true) and the combobox has a selected value and the combobox is removed and readded in the visual tree during a SizeChange event, the following exception is thrown: "value does not fall within the expected range".
I managed to reproduce this error in the example code. Is this a Silverlight 5 issue/bug or am I doing something wrong?
<UserControl x:Class="SilverlightApplication3.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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
</Grid>
</UserControl>
code behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
namespace SilverlightApplication3
{
public partial class MainPage : UserControl
{
private ComboBox combo;
private Button b;
public MainPage()
{
InitializeComponent();
combo = new ComboBox() { Width = 100, Height = 20 };
combo.Items.Add(new ComboBoxItem() { Content = "Jaar", IsSelected = true});
LayoutRoot.Children.Add(combo);
LayoutRoot.SizeChanged += new SizeChangedEventHandler(LayoutRoot_SizeChanged);
b = new Button() { Content = "Crash Me" };
b.Click += new RoutedEventHandler(b_Click);
Grid.SetRow(b, 1);
LayoutRoot.Children.Add(b);
}
void b_Click(object sender, RoutedEventArgs e)
{
combo.IsDropDownOpen = true;
Width = 500;
}
void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
{
LayoutRoot.Children.Clear();
LayoutRoot.Children.Add(b);
LayoutRoot.Children.Add(combo);
}
}
}

Wpf Event in XAML cannot get the right focus on button

I try to make the button move when I press an arrow key on the keyboard.
But what I get is that I always need to press the button with mouse to get the right focus first, and then I can move it with the left arrow key, otherwise not. However, as what I know, the KeyDown event is triggered by the Grid instead of the button.
Here is how I do it in the Code behind:
private void Panel_KeyDown(object sender, KeyEventArgs e)
{
Button source = Baffle;
if (source != null)
{
if (e.Key == Key.Left)
{
source.Margin = new Thickness(source.Margin.Left - 1, source.Margin.Top,
source.Margin.Right + 1, source.Margin.Bottom);
}
}
}
The XAML:
<Grid Name="Panel" KeyDown="Panel_KeyDown" Background="BlanchedAlmond">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Name="Baffle" Template="{StaticResource ButtonTemplate}"
Grid.Row="1" VerticalAlignment="Bottom" Margin="20" HorizontalAlignment="Center"
Width="50" Height="20"/>
</Grid>
Could anyone explain this? Thanks.
Interesting ... Not sure why, but if you want to solve it in a simple way you can use this:
public partial class MainWindow : Window
{
private Button source;
public MainWindow()
{
InitializeComponent();
source = Baffle;
source.Focus();
}
private void Panel_KeyDown(object sender, KeyEventArgs e)
{
if (source != null)
{
if (e.Key == Key.Left)
{
source.Margin = new Thickness(source.Margin.Left - 1, source.Margin.Top,
source.Margin.Right + 1, source.Margin.Bottom);
}
}
}
}
(simply give that button the focus on load,and you can move it to your heart content).
That's right - your KEYDOWN event fires only when Grid(Panel) has focus on it. But when your application starts it hasn't focus on it and will get it only when you select any control on Grid for example this button or another one. MainWindow has focus on start so just add this event handler to MainWindow KeyDown.
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" KeyDown="Panel_KeyDown">
<Grid Name="Panel" Background="BlanchedAlmond">
.....
This is because Grid by default is not focusable, so the KeyEvent is not going to work until the Grid has focus or one of the controls in the Grid FocusScope has logical focus.
You can set the Grid to Focusable and set the FocusedElement using FocusManager to the Grid and this will work
Example:
<Grid Name="Panel" KeyDown="Panel_KeyDown" Background="BlanchedAlmond" FocusManager.FocusedElement="{Binding ElementName=Panel}" Focusable="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Name="Baffle"
Grid.Row="1" VerticalAlignment="Bottom" Margin="20" HorizontalAlignment="Center"
Width="50" Height="20"/>
</Grid>

Moving items from one Grid to another

OK, here's my XAML:
<Window x:Class="nathan___visual_studio_panes___layers.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<StackPanel DockPanel.Dock="Top">
<Button Name="move_ellipse2_to_GridA" Click="move_ellipse2_to_GridA_Click">
Move ellipse2 to GridA
</Button>
<Button Name="move_ellipse3_to_GridA" Click="move_ellipse3_to_GridA_Click">
Move ellipse3 to GridA
</Button>
</StackPanel>
<Grid Grid.IsSharedSizeScope="True" Background="AliceBlue">
<Grid Name="gridA">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="0" Grid.Row="0" Fill="CornflowerBlue"/>
</Grid>
<Grid Name="gridB" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="1" Name="ellipse2" Fill="Aquamarine"/>
<GridSplitter Name="gridB_grid_splitter" Width="5" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
<Grid Name="gridC" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="1" Name="ellipse3" Fill="Cornsilk"/>
<GridSplitter Name="gridC_grid_splitter" Width="5" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
</Grid>
</DockPanel>
</Window>
And here's the code behind:
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 nathan___visual_studio_panes___layers
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ColumnDefinition GridA_column_for_ellipse2 = new ColumnDefinition();
ColumnDefinition GridA_column_for_ellipse3 = new ColumnDefinition();
public MainWindow()
{
InitializeComponent();
}
private void move_ellipse2_to_GridA_Click(object sender, RoutedEventArgs e)
{
gridB.Children.Remove(gridB_grid_splitter);
var i = gridA.ColumnDefinitions.Count;
gridA.ColumnDefinitions.Add(GridA_column_for_ellipse2);
gridB.Children.Remove(ellipse2);
gridA.Children.Add(ellipse2);
Grid.SetColumn(ellipse2, i);
var grid_splitter = new GridSplitter() { Width = 5, HorizontalAlignment = HorizontalAlignment.Left };
gridA.Children.Add(grid_splitter);
Grid.SetColumn(grid_splitter, i);
Console.WriteLine(i);
}
private void move_ellipse3_to_GridA_Click(object sender, RoutedEventArgs e)
{
gridC.Children.Remove(gridC_grid_splitter);
var i = gridA.ColumnDefinitions.Count;
gridA.ColumnDefinitions.Add(GridA_column_for_ellipse3);
gridC.Children.Remove(ellipse3);
gridA.Children.Add(ellipse3);
Grid.SetColumn(ellipse3, i);
var grid_splitter = new GridSplitter() { Width = 5, HorizontalAlignment = HorizontalAlignment.Left };
gridA.Children.Add(grid_splitter);
Grid.SetColumn(grid_splitter, i);
Console.WriteLine(i);
}
}
}
If I start the program and click the "Move ellipse2 to GridA" and "Move ellipse3 to GridA" buttons, I get "the right thing". I.e. the three ellipses and two grid splitters all appear in the window.
However, if I start the program, drag the grid splitter (which moves ellipse3), click "Move ellipse2 to GridA", drag the grid splitter for ellipse2 (the green one), and finally click "Move ellipse3 to GridA", ellipse3 disappears completely!
What am I doing wrong here? :-) I.e. pushing both buttons should lead to all three ellipses showing up in the window, regardless of any splitter dragging.
I know this is kind of a weird demonstration program. One of the examples in Adam Nathan's WPF Unleashed is a model of the Visual Studio start screen. The demo program above is just exploring a different technique for docking/undocking the panes.
Thanks for any hints or tips. I'm a WPF newb. :-)
The solution
Place following code at the end of move_ellipse3_to_GridA_Click method
foreach (ColumnDefinition column in gridA.ColumnDefinitions)
column.Width = new GridLength(1, GridUnitType.Star);
The explanation
The problem is that GridSplitter modifies ColumnDefinition.Width. It remaines star, but it becomes something like "357*". That's why the last column in gridA becomes vanishingly small. You can see it if you place breakpoint at the beginning of move_ellipse3_to_GridA_Click handler, reproduce your "bad" scenario and press that button second time. Check gridA.ColumnDefinitions[0] and [1] Width there.
Awareness
Just for making the world better: it is advised to place GridSplitter in a dedicated ColumnDefinition (RowDefinition) with Width (Height) set to Auto, and the GridSplitter's alignments to Center and Stretch.
Also there's no need to define RowDefinition or ColumnDefinition if there's only one of them and there's no need to set element's Row or Column to 0 - it is by default.

Categories

Resources