WPF hides line, but does not sweep white space
I have a wpf window with a grid. I would like to hide the lines and I am doing with this code as shown in other stackoverflow threads:
buttonsGrid.Visibility = Visibility.Collapsed; or buttonsGrid.Height = 0;
dayTimePicker.Visibility = Visibility.Collapsed; or dayTimePicker.Height = 0;
Setting the visibility for collapse or height to 0 gives the same effect, but I would like the space these rows are to scroll ... I would like the whole window to be occupied by indexed row 0 ... How can I do this?
This is my window:
<Window x:Class="PerformanceVideoRec.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:DTControl="clr-namespace:DayTimePickControl"
Title="{StaticResource ID_TITLE}" Height="600" Width="900" Loaded="Window_Loaded"> <!--Closing="Window_Closing"> -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" x:Name="ControlPart" IsEnabled="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" x:Name="LeftGrid">
<Grid.RowDefinitions>
<RowDefinition Height="55*"/>
<RowDefinition Height="5*"/>
<RowDefinition Height="5*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<WindowsFormsHost Grid.Row="0" Margin="5" Background="Gray">
<wf:PictureBox x:Name="playWindow"></wf:PictureBox>
</WindowsFormsHost>
<UniformGrid Grid.Row="1">
<Button x:Name="btnShowHideControls" Content="Nascondi Controlli" Click="btnShowHideControls_Click"/>
</UniformGrid>
<UniformGrid Columns="6" Grid.Row="2" x:Name="buttonsGrid">
<Button x:Name="btnPause" Margin="5" Width="50" Content="{StaticResource ID_PAUSE}" Click="btnPause_Click"></Button>
<Button x:Name="btnPlay" Margin="5" Width="50" Content="{StaticResource ID_PLAY}" Click="btnPlay_Click" Visibility="Collapsed"/>
<Button x:Name="btnStop" Margin="5" Width="50" Content="{StaticResource ID_STOP}" Click="btnStop_Click"></Button>
<Button x:Name="btnSlow" Margin="5" Width="50" Content="{StaticResource ID_SLOW}" Click="btnSlow_Click"></Button>
<TextBox x:Name="tbSpeed" IsEnabled="False" Width="50" Height="25" TextAlignment="Center" VerticalContentAlignment="Center" Text="1X" />
<Button x:Name="btnFast" Margin="5" Width="50" Content="{StaticResource ID_FAST}" Click="btnFast_Click"></Button>
<Button x:Name="btnNormal" Margin="5" Width="50" Content="{StaticResource ID_NORMAL}" Click="btnNormal_Click"></Button>
</UniformGrid>
<DTControl:DayTimePick x:Name="dayTimePicker" Grid.Row="3" Width="550" Height="100" Grid.RowSpan="2" OnTimeClick="dayTimePicker_OnTimeClick"></DTControl:DayTimePick>
</Grid>
<Frame x:Name="PlayBackFrame" Grid.Column="1" Background="AliceBlue" ></Frame>
</Grid>
</Grid>
source to share
MVVM way:
- create a separate view model for the part of the user interface that you want to collapse. Let's call it PlayViewModel,
- create a DataTemplate for it,
-
exposes it as a property (e.g. let it play, remember to raise the property change event) on the view model, which is the DataContext for the whole view
-
you display it in your grid with ContentPresenter, ContentPresenter.Content bound to Play property.
-
You are hiding by the null Play property, you are showing it by restoring it.
You get the opportunity to test for free.
source to share
You can use Data Binding and bind the Visibility
control property inside the string you want to collapse with the converter.
I usually use the Mvvm Light NuGet package , documentation , to have some functionality when using data binding. (In this case, the implementation RelayCommand
, RaisePropertyChanged
)
The simplest example:
Part of the review. Here you can notice the binding between the Visibility
button property and the property IsButton1Visible
ViewModel
. Of course, bool
and Visibility
are not the same type, so I had to create a mapping using IValueConverter
:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="1" Visibility="{Binding IsButton1Visible, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Button Grid.Row="1" Content="2" />
<Button Grid.Row="2" Content="3" />
<Button Grid.Row="3" Content="4" />
<Button Grid.Row="4" Content="Toggle button 1 visibility" Command="{Binding ToggleButton1Visibility}" />
</Grid>
The window constructor in the code behind (you can also bind ViewModel
with a property DataContext
directly in View
), used to bind View
with ViewModel
:
public MainWindow()
{
InitializeComponent();
this.DataContext = new MyWindowViewModel();
}
Converter to convert true
to Visibility.Visible
:
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> (bool)value ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
App.xaml
, the Application.Resource
part used to convert the View
"to" converter:
<Application.Resources>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Application.Resources>
ViewModel. The RaisePropertyChanged
method is set
IsButton1Visible
very important here because it notifies View
that the property has changed, so it View
can update itself:
public class MyWindowViewModel : ViewModelBase
{
private bool _isButton1Visibile = true;
public bool IsButton1Visible
{
get => _isButton1Visibile;
set
{
if (_isButton1Visibile == value)
return;
_isButton1Visibile = value;
RaisePropertyChanged(nameof(IsButton1Visible));
}
}
RelayCommand _toggleButton1Visbility;
public RelayCommand ToggleButton1Visibility
{
get
{
return _toggleButton1Visbility ?? (_toggleButton1Visbility = new RelayCommand(
() =>
{
IsButton1Visible = !IsButton1Visible;
}));
}
}
}
source to share
LeftGrid.RowDefinitions[2].Height = new GridLength(0);
LeftGrid.RowDefinitions[3].Height = new GridLength(0);
If you want to restore, do this
LeftGrid.RowDefinitions[2].Height = new GridLength(5, GridUnitType.Star);
LeftGrid.RowDefinitions[3].Height = new GridLength(20, GridUnitType.Star);
source to share