My problem is: I can't find out how to toggle the visibility of my WPF grid column. Assume following XAML markup:
<Grid x:Name="myGrid">
<Grid.RowDefinitions>
<RowDefinition x:Name="Row1" />
<RowDefinition x:Name="Row2" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" />
<ColumnDefinition x:Name="Column2" />
</Grid.ColumnDefinitions>
</Grid>
Aferwards the grid is filled with some controls etc. Now I want to hide a single column dynamically out of my C# code. I've tried achieving this by setting the the column's definition width to zero, e.g. Column1.Width = 0. This works, but I don't really like this solution - is there really no better way?
I'm looking for something like myGrid.Columns[0].Visibility = COLLAPSED or Column1.Visibility = HIDDEN. I just can't find something like that - any ideas?
<ColumnDefinition>
<ColumnDefinition.Style>
<Style TargetType="ColumnDefinition">
<Setter Property="Width" Value="*" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsColumnVisible}" Value="False">
<Setter Property="Width" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</ColumnDefinition.Style>
</ColumnDefinition>
Please do implement INotifyPropertyChanged in your ViewModel
The simplest way to do this is to add a named Grid as the top level control in the relevant column that you want to hide. Then you can just hide it and all of its contents as you would any other control:
In XAML:
<Grid x:Name="myGrid">
<Grid.RowDefinitions>
<RowDefinition x:Name="Row1" />
<RowDefinition x:Name="Row2" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" />
<ColumnDefinition x:Name="Column2" />
</Grid.ColumnDefinitions>
<Grid x:Name="GridColumn1" Grid.Column="1">
...
</Grid>
</Grid>
Then in code behind:
GridColumn1.Visibility = Visibility.Collapsed;
As you have more than one row in your Grid, you may want to rearrange them like this:
<Grid x:Name="myGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" />
<ColumnDefinition x:Name="Column2" />
</Grid.ColumnDefinitions>
<Grid x:Name="GridColumn0" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
<Grid x:Name="GridColumn1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
</Grid>
UPDATE >>>
It is not really necessary to rearrange the main Grid like this... you could just as easily add two Grid controls, one in each row of the relevant column and then set the Visibility of them both together:
InnerGrid1.Visibility = InnerGrid2.Visibility = Visibility.Collapsed;
You could even add a Grid into each cell of the main Grid and have full control over which cells are visible at any one time.
In WPF Grid Column and Row Hiding on Code Project, they show a way using dependency properties. They set Visible = false, but internally, it sets Width = 0.
Another idea is to delete the column definition in code behind... But I guess it's an even worse hack! :(
An ugly hack would be to just change the width to 0 (out of sight, out of mind).
There are many reasons why you shouldn't do this but, based upon your situation, it may suffice!
Use following to Hide the grid. Similarly you can hide the row definitions and column definitions using Name property.
myGrid.Visibility = System.Windows.Visibility.Hidden;
Related
I'm trying to extend the Calendar control into my own that has some dependency properties for setting things like the hover colors, highlight of the current day, and so on. I've got all of my properties and hook them up using bindings, but for some reason, the text displayed for the day of the week heading will not change its font color or style. At first I thought it was my bindings because I'm using a RelativeSource and finding the ancestor type, but I then tried setting them explicitly in the DataTemplate but nothing works.
Is this an inheritance issue from the Calendar base? Or is there something going on internally that's overriding my template? Here's my DataTemplate for the CalendarItem:
<DataTemplate x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}">
<TextBlock Foreground="Red"
FontWeight="Bold"
FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=local:CalendarControl}}"
FontFamily="Arial"
HorizontalAlignment="Center"
Margin="0,6,0,6"
Text="{Binding}"
VerticalAlignment="Center" />
</DataTemplate>
The way I understand it from here, this DataTemplate is used to dynamically generate items for these which are then inserted into the "PART_MonthView" grid below:
<Grid x:Name="PART_MonthView"
Grid.ColumnSpan="3"
TextElement.FontFamily="Arial"
HorizontalAlignment="Center"
Margin="6,-1,6,6"
Grid.Row="1"
Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
Is this DataTemplate even the right template? When you view the control in runtime and use snoop to browse the visual tree, you can see the text blocks being inserted into the grid but the values are coming from a local source:
I'm stumped and can't find any concrete answers on how to style this stuff. Am I better off building my own UI and then just watching property values to see if they change? Any help is greatly appreciated.
The following page from MSDN describes the XAML for styling a calendar in full:
Calendar Styles and Templates
By modifying the value for the FontSize, FontWeight, and FontFamily attributes in the ControlTemplate for CalendarItem it is possible to modify the font appearance.
Here is an after picture with the font size bumped up to 16.
I think this is the easiest way to do you what you want. Make a new ControlTemplate for Calendar using the XAML from the example and then make your alterations.
I have an WPF application that contains a grid. The grid is split into 3 columns with the 3rd grid having zero width upon loading.
I have two datagrids in the other two columns. When the selected item in one of the datagrid changes the other datagrid changes it display values, i.e. a master detail template. This all works fine.
There is one value in the datagrid that if selected I wish this 3rd column to changes its width from zero to 2*. I don't know how to do this?
EDIT
I wish to achieve this through XAML. I have been looking at data triggers & value converters. I written some code below quickly to test. I have read that setting the column to width=0 there is probably higher on the dependency property setting precedence list. Is there anyway to do this or will I need to use code behind?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="0"/>
</Grid.ColumnDefinitions>
<DataGrid Grid.Column="0"
ItemsSource="{Binding OrderList}"
SelectedItem="{Binding OrderSelected}"
AutoGenerateColumns="True">
</DataGrid>
<TextBox Grid.Column="1" Text="{Binding OrderSelected.Name}">
</TextBox>
<Grid x:Name="columnHideSeek" Grid.Column="2" Background="Blue">
<Grid.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding OrderSelected.Name}" Value="Mark">
<Setter Property="Grid.Width" Value="10"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
</Grid>
Your XAML file should looks like this:
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Name="thirdColumn" Width="0"/>
</Grid.ColumnDefinitions>
</Grid>
And selected datagrid event scope in your code behind file:
GridLength g2 = new GridLength(2, GridUnitType.Star);
thirdColumn.Width = g2;
I am just wondering if it is possible to add hyperlink to WPF window title and if it is possible what is the best way of doing that.
I want to have title like that:
Program name, Version and that link to my site (e.g http://mysite.com)
This isn't supported out-of-the-box.
However, you can use Control Template to achive this or create an entire custom window of your own.
you can create a control template for your window. Something like that :
<Window.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0">
<Hyperlink NavigateUri="http://mysite.com">
My Program, version 1
</Hyperlink>
</TextBlock>
<!-- Implement your own control box control -->
<ContentPresenter />
</Grid>
</ControlTemplate>
</Window.Template>
You'll also have to set the window's Style to None as follows:
WindowStyle="None"
This will also mean that you'll have to implement your own controlBox with minimize, maximize and close buttons.
Check out this links for further information:
http://www.codeproject.com/Articles/140267/Create-Custom-Windows-in-WPF-with-Ease
http://blog.magnusmontin.net/2013/03/16/how-to-create-a-custom-window-in-wpf/
Good luck
In WPF, I have this simple Grid
<Grid>
<Label Content="Firstlabel" />
<Label Content="Secondlabel" />
</Grid>
and when I run it , they both are placed right on top of each other so you can't see the SecondLabel, only FirstLabel is visible.
Now , obviously I am not using any margins,or dockpanel/stackpanel/Wrappanel.
I would have thought that like HTML Divs ( I know , comparing apples & oranges), the SecondLabel will simply be put *next*to the FirstLabel, leaving both visible.
So one *must*use a layout container in this situation or is there an alternative?
Thanks
I think you must use a layout container. However, Grid is also a layout container. If you don't want to use a StackPanel or any other control which behaves like you described, you can also define rows and columns inside of a Grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="Firstlabel" Grid.Row="0" />
<Label Content="Secondlabel" Grid.Row="1" />
</Grid>
You can also set the width of the RowDefinition.
I think that what you are looking for, are the columndefinitions:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<Grid.ColumnDefinitions>
<Label Content = "FirstLabel" Grid.Column="0" />
<Label Content = "SecondLabel" Grid.Column="1" />
</Grid>
Hope this helps.
I have defined grid in xaml like this:
<Grid Name="grdMoney" HorizontalAlignment="Center" Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
... Content, many Textboxes in each row
</Grid>
Now I just want to highlight some row by changing background in that row. But I can't find out how can I get exact row from grid in code. I think it's easy but I am googling for last 15minutes and can't find it. Maybe something with grdMoney.Childer[number_of_row]? Thanks for help
Grid is a Panel. Panels are responsible for layouting, nothing more.
If you want to update background - put content of every row to Border, and find appropriate Border like that (i wrote code here, and didn't test it, but should work):
int desiredRowId = 2;
foreach(var child in grdMoney.Children.OfType<Border>())
{
if (Grid.GetRow(child) == desiredRowId)
{
child.Background = new SolidColorBrush(Colors.Red);
}
}
I've probably'll do this in xaml using DataTriger
In data triger you can check your condition and apply appropriate background