silverlight column header disappers on applying header style template - silverlight

I have a Silverlight DataGrid with two columns. The headers of these two columns header have to be shown with a text box and column header title or name so that the text box can be used for filtering later.
So, I have used the following code to display the text box using a style:
<Style x:Name="mytemplate"
x:Key="mytemplate"
xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
TargetType="dataprimitives:DataGridColumnHeader">
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate x:Name="ColHeaderTemplategrid">
<StackPanel>
<TextBox x:Name="txtfilterBox" KeyDown="txtfilterBox_KeyDown" Width="40"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
and I have applied the style to the column headers as below:
((DataGridTextColumn)column[0]).HeaderStyle = mytemplate;
((DataGridTextColumn)column[1]).HeaderStyle = mytemplate;
The thing is, now the text box is visible but the column header title or name disappears?
How do I show my column header along with the text box?

As u said i just inserted textblock in to the stackpanel of the template and solves the problem
the code is below
<Style x:Name="mytemplate" x:Key="mytemplate" xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
TargetType="dataprimitives:DataGridColumnHeader">
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate x:Name="ColHeaderTemplategrid">
<StackPanel>
<TextBlock Text="{Binding}" ></TextBlock>
<TextBox x:Name="txtfilterBox" KeyDown="txtfilterBox_KeyDown" Width="40"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

Related

How to fit width image with datagridcell width

This is my problem : The only way to select the row is to click on the image (green circle).
What I would like to do : When I click on the DataGridCell, not only the image, the entire row is selected.
I have DataGridTemplateColumn to display images in DataGrid.
I setted SelectionMode="Single" SelectionUnit="FullRow" as DataGrid properties.
But if I don't click EXACTLY on the image, the row won't be selected.
SCREESHOTS
I made some screenshots to explain it more clearly :
Size of the image :
Size of the DataGridCell
So, in my opinion, the problem can come from 2 things :
The size image doesn't fit the entire cell, so that's why, but how can I fit it ?
The Cell select is disabled, and I can enabled it
Thanks for your time !
EDIT 1
<DataGridTemplateColumn Header="{Binding, Source={StaticResource proxy}}" HeaderStyle="{StaticResource }" ClipboardContentBinding="{Binding}">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<Grid>
<Image Source="{Binding }" Style="{DynamicResource }" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
For those who wants to know what it was about :
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<ContentPresenter Padding="5,1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
This made the image bug... I don't know why, but it loses the effect to click around the image... Don't know more, I used another way to add Padding to rows.
Use Margin instead of Padding.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Margin="5,1">
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

Bind header textblock isEnabled to parent Groupbox isEnabled

Referencing to this question: WPF Databinding: How do I access the "parent" data context?
I wanna do something similiar, but for the header of a Groupbox (because the header does not concern with the Box is being disabled and thus is always black while the rest is light gray. This looks a bit strange to me if all the content of the box is gray, the above is gray, but the box title itself stays black.
So I tried to use the approach mentioned in the linked question by flq to simply bind the isEnabled property of the header textblock to the isEnabled property of the groupbox but it seems that my binding at some point fails and I don't know where and why exactly.
heres my current code:
<GroupBox Header="Change Steps" Grid.Row="2" Grid.ColumnSpan="3" Name="gbChangeSteps">
<GroupBox.Style>
<Style TargetType="GroupBox">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontWeight="Bold" Height="19" Foreground="Black" IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=isEnabled}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupBox.Style>
<!-- ... (some non relevant Content)-->
</GroupBox>
after additional research I found the post Disable groupBox including the groupBox name in WPF
that lead me, in combination with Properties->Create Databinding->Binding type->UIElement to the solution that fixed both problems, the one this question was about and the original one that lead to entire restyling, which was that letters like the small g got messed up in the header.
This is the code that fixed the issue:
<GroupBox.Style>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontWeight="Bold" Height="19" IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UIElement}}}">
<TextBlock.Style>
<Style>
<Style.Triggers>
<Trigger Property="Control.IsEnabled" Value="False">
<Setter Property="Control.Foreground" Value ="#FF6D6D6D" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupBox.Style>

Excess border selection in WPF's Lisbox [duplicate]

I have a ListBox in which each item is a StackPanel. The StackPanel consist of an Image and a TextBlock below it:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImageFilePath}"/>
</Image.Source>
</Image>
<TextBlock Text="Title" TextAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
It looks like this:
When the user select an item, I get the default blue rectangle that surround the StackPanel:
Now, I want to make a different border for the selected-item, but I want it to surround only the image.
I know how to make a control template and put a custom border around the ContentPresenter, but this, of course, will surround the whole StackPanel, not only the Image.
I don’t know if making changes to the ContentPresenter is possible, and if it is a good idea at all. If there is other way to achieve the look I want, it will be fine as well.
Right, the ListBox's own ContentPresenter isn't helpful for what you're doing. You want to a) eliminate the ListBox's own selection visuals and b) replace them with something more suitable in the DataTemplate for your items.
The default selection visual is applied by the default template for ListBoxItem. So replace that template. Using a Style in the resources for your ListBox, apply your own control template to ListBoxItem. Not much to it, just present the content and don't provide a selection background. Then you handle the selection visuals with a trigger in your data template, where your image and your label are defined and you can apply changes to one and not the other. The below example works for me.
Note that there's some fiddling with the HorizontalAlignment on the Border element to make it cling to the Image element within it. Also, I wrote a quickie test viewmodel whose Items property is called Items; I assume this is not the name of the collection member you're using to populate your own ListBox.
<ListBox
Margin="8"
ItemsSource="{Binding Items}"
>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border
x:Name="HighlightBorder"
BorderThickness="4"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10"
>
<Border.Style>
<Style TargetType="Border">
<!-- MUST set default BorderBrush via a style, if you set it at all.
As an attribute on the Border tag, it would override the effects of
the trigger below.
-->
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Border.Style>
<Image Source="{Binding ImageFilePath}" />
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True">
<Setter TargetName="HighlightBorder" Property="BorderBrush" Value="Orange" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

How do I enable text wrapping on all column headers?

How does one enable text wrapping on all column headers of a DataGrid, without disabling the other default header functionality? Such as column resizing, sort direction indicator, etc which are needed.
Is there a way to do this?
Or don't bother with the primitives in the app.xaml file and do the following (my objects):
<DataGrid Name="WBdataGrid" AutoGenerateColumns="False" ColumnHeaderHeight="50" >
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding}"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns> ...
I would like to enable text wrapping
on all column headers of my DataGrid,
without disabling the other default
header functionality
You need to add the following namespace to your app.xaml file:
xmlns:primitives="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"
and then add this tag to app.xaml:
<Style TargetType="{x:Type primitives:DataGridColumnHeader}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding}"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
This will add text-wrapping to the headers of all of your DataGrids throughout your WPF application.
While we're on the subject, if you just wanted to center the text of each of your DataGrid headers, you could do this using the following style instead:
<Style TargetType="{x:Type primitives:DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
Yet I've seen so many WPF articles suggesting that you can only do this by adding TextWrapping or HorizontalAlignment on each DataGrid column individually:
<toolkit:DataGridTextColumn Binding="{Binding Path=TaxAmount}">
<toolkit:DataGridTextColumn.HeaderTemplate >
<DataTemplate>
<TextBlock Text="Tax Amount" Width="90" TextWrapping="Wrap" HorizontalAlignment="Center"/>
</DataTemplate>
</toolkit:DataGridTextColumn.HeaderTemplate>
</toolkit:DataGridTextColumn>
I added
to the header text where I want the text to wrap. This is useful when you don't need to bind your header text to something
<DataGridTextColumn x:Name="cAccountNumber"
Header="Account
Number"
Width="80"
Binding="{Binding Path=AccountNumber}" />
Instead of assigning the column name directly to the DataGridColumn.Header property, I created a TextBlock containing the column name, set the TextWrapping property of the TextBlock to "Wrap" and assigned the TextBlock to the DataGridColumn.Header property. This preserves the default header functionality.
Example:
<toolkit:DataGridTextColumn Binding="{Binding Path=MyProperty}">
<toolkit:DataGridTextColumn.Header>
<TextBlock Text="Something Longer" TextWrapping="Wrap" />
</toolkit:DataGridTextColumn.Header>
</toolkit:DataGridTextColumn>
You could create a global Style for your column headers. Without any example mark-up I don't know the syntax, but it should look something like this:
<Style TargetType="{x:Type dg:ColumnHeader}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
Since the Style is key-less, it will automatically be applied to all of your column headers. And styles will not override any locally set properties, so it won't "disable" any existing header functionality.

WPF button textwrap style

How do I change the default textwrapping style of a button in WPF?
The obvious solution of:
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
doesn't work, because Textwrapping isn't a settable property here, apparently.
If I try:
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock Text="{Binding}" Foreground="White" FontSize="20" FontFamily="Global User Interface" TextWrapping="Wrap"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I just get a worthless response from the compiler:
Error 5 After a 'SetterBaseCollection' is in use (sealed), it cannot be modified.
Removing the ControlTemplate tag keeps the error.
The following attempt yields a different error:
<Setter Property="TextBlock">
<TextBlock Text="{Binding}" Foreground="White" FontSize="20" FontFamily="Global User Interface" TextWrapping="Wrap"/>
</Setter>
Error 5 The type 'Setter' does not support direct content.
I see that I can set the textwrapping for each button individually, but that's pretty asinine. How can I do it as a style? What are the magic words?
And for future reference, where can I find a list of these magic words, so I can just do this on my own? The MSDN entry is pretty useless when I try to find out about which properties can be set by the setter.
To expand Eric's answer with an example:-
<Button Name="btnName" Width="50" Height="40">
<TextBlock Text="Some long text" TextWrapping="Wrap" TextAlignment="Center"/>
</Button>
I solved this problem by adding a TextBlock to the button, and using it to display the button text instead of the button's Content property. Be sure to set the TextBlock's height property to Auto, so that it grows in height to accommodate the number of lines of text as it wraps.
Your second version should work, and does for me, with the caveat that you need to change the TextBlock Text binding:
<!-- in Window.Resources -->
<Style x:Key="fie" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock Text="{TemplateBinding Content}" FontSize="20" TextWrapping="Wrap"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- then -->
<Button Style="{StaticResource fie}">verylongcaptiongoeshereandwraps/Button>
Note this completely replaces the button style (i.e. you will need to create your own button chrome if you want it).
Regarding your second question, all writeable dependency properties can be set using a Setter. The reason you were unable to set TextWrapping on a Button via a style is that Button does not have a TextWrapping dependency property (or indeed any TextWrapping property). There are no "magic words," just the names of dependency properties.
<Style TargetType="Button">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{TemplateBinding Content}" TextWrapping="Wrap" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Here's an example of Eric's answer in C# code-behind:
var MyButton = new Button();
MyButton.Content = new TextBlock() {
FontSize = 25,
Text = "Hello world, I'm a pretty long button!",
TextAlignment = TextAlignment.Center,
TextWrapping = TextWrapping.Wrap
};
To expand #Rob's answer with #fadden's comment:
<Button Width="50" Height="40">
<AccessText Text="_Some long text" TextWrapping="Wrap" TextAlignment="Center"/>
</Button>
The TextBlock control does not support keyboard hotkeys (_).

Resources