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.
Related
I want to create a dataGrind in WPF c# with different type of cells in same column to take user input.
My DataGrid should looks like this:
So how will I format Name and Age cells to textbox cell. Gender and State cell to Combobox cell?
If you require more fields in the future, and want to reuse some of the functionality, take a look at the WPF Property Grid.
If your rows are fixed in this layout and you don't expect them to change frequently, you can consider an alternative approach using a standard grid:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock>Name</TextBlock>
<TextBlock Grid.Row="1">Age</TextBlock>
<TextBlock Grid.Row="2">Gender</TextBlock>
<TextBlock Grid.Row="3">State</TextBlock>
<TextBox Grid.Column="1"></TextBox>
<TextBox Grid.Row="1" Grid.Column="1"></TextBox>
<ComboBox Grid.Row="2" Grid.Column="1"></ComboBox>
<ComboBox Grid.Row="3" Grid.Column="1"></ComboBox>
</Grid>
If you use the MVVM-Pattern then (I think so) you shoud create a ViewModel for cells and bind it as ItemSource. In your ViewModel you can set the Elements that you need. It should be possible to change between TextBoxes and ComboBoxes.
Possible you find here the answer:
WPF DataGrid with different UserControl in each Cell;
WPF DataGrid different edit controls within a single column
http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector
P.S. Its not enough for an answer, but I have not enough Points to comment the question.
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;
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.
So I'm pretty new to WPF and I'm having trouble with the layout of my Window. Currently I have a WPF application with a Grid defined as such:
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
In the very top row, spanning two columns, I have a Menu. In the second row I have some Labels in the first column and an Image and a WindowsFormsHost in the second, finally, in the third row I have a graphing control in the second column. By default, I set the size of the Image and WFH to 570 x 413. Now, I'd like for both the Image and WFH to expand when my Window is resized such that they maintain the same relative (to the Window) size. (I actually would like the same to happen to my graphing control as well, but I can probably figure that one out if I can get the others. I cannot for the life of me figure out what setting I need to turn on/off or what I might need to bind or whatever in order to make this happen. Any help is greatly appreciated!
Thanks!
Have you tried:
<RowDefinition Height="*" />
Make sure to assign your Grid.Row within your image or control, but do not sign the controls height/width properties. The control should autosize with expansion.
Update
Did a quick test to make sure this works.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="Example"/>
<Image Grid.Row="1" Source="c:\Example.jpg"/>
<Label Grid.Row="2" Content="Example2"/>
</Grid>
The image expands with the application based on the image's proportions. It does expand, but it keeps it's dimensions along with the full image in view. If you were to change the rowdefinition from ***** to Auto, you will notice that the image will expand, but it will expand past your view. Meaning you will not always see the full image.
I would suggest making a simple application like above, and playing with constraints to figure out what each does.
You need to show more information in your description, because all of the properties of the Grid and of the Image, etc. will factor into the layout.
However, you probably want to look at the HorizontalAlignment and VerticalAlignment properties of your Grid and of your Image, as well as the Stretch property of the Image. Also, you don't want to specify a fixed size for the image (you can specify a MinWidth and a MinHeight if you want them to be a certain size when starting up).
Here's a quick example that shows a grid filling a window, with a scaling image.
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Content="First Row" />
<Label Grid.Column="0" Grid.Row="1" Content="Column 0, Row 1" />
<Image Grid.Column="1" Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="Resources\ExamplePicture.png"
Stretch="Uniform" />