TextBlock internal margin - silverlight

I suppose when several TextBlocks are located in a row(i.e in StackPanel with the Horizontal orientation) they should look as if it was one TextBlock. But I found the following:
The first line is a TextBlock displaying "eeee". The second one is a StackPanel containing 4 TextBlocks and each TextBlock contains "e". As you can see from the picture above, the second line is a little bit longer than the first one. It looks like the TextBlocks have some internal margin. But, in my case, I'd like to prevent it.
So, do you know how to do it?

Try setting the Padding and Margin of the TextBlock to zero.
<TextBlock Padding="0" Margin="0" ... />
Since you have multiple textblocks that you are going to want to do this with, you should probable use a Style to do this.
<StackPanel Orientation="Horizontal">
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
</Style>
...
</StackPanel>
If this doesn't help, then you could start using negative margins:
Margin="-1,0,0,0"
However this introduces brittleness into your code, because the spacing between text depends on the font size and the text displayed. For example, if you change the font size to 13, you will no longer have this problem with five lower case 'e'. Changing the text to uppercase 'E' will result in the same problem, though.
You could try using the clipping properties on the TextBlock or even the rendering affects, but this seems like a lot of work just to get text to adjust a couple of pixels. May I ask why you are trying to get the two text samples to look the same?
Update:
I am doubtful that you can find a good way to make this work the way that you want to. May you should look into using a RichTextBox or creating a custom control.
Here is a good example use of a RichTextBox with text highlight (although it is foreground highlighting).

Related

WPF AutoCompleteBox popup height

I'm trying to figure out how to increase the popup height of WPF Toolkit's AutoCompleteBox. Right now, only few items fit in the popup. How do I make it taller? I see there is a MaxPopupHeight property. What about min height?
I don't know if this is exactly what you want, but a thing I've found useful is to specify an explicit height for the popup:
<tk:AutoCompleteBox ...>
<tk:AutoCompleteBox.Resources>
<Style TargetType="{x:Type Popup}">
<Setter Property="Height" Value="200" />
</Style>
</tk:AutoCompleteBox.Resources>
</tk:AutoCompleteBox>
This also helps with the problem of Toolkit's AutoCompleteBox ignoring MaxDropDownHeight as several people have encountered.
Actually now I see that it's pretty much an elaboration on a solution proposed by Zabavsky.

wpf combobox trigger for Validation.HasError

I've looked around, but can't specifically find my issue. I know that the default "Error" handling within WPF puts an "Adorner" around controls in case there are any errors based on IDataErrorInfo or Validataion rules failing a given control. That's all good and fine, however, with a tabbed page interface, if any controls are so flagged as invalid, they are properly adorned in red border. However, as soon as you go from tab page 1 to 2 and back to 1, all the adorners are gone (bad). This was already asked, and solution accepted, but was looking for a better alternative.
So, I went to my "Themes" declaration, and for the textbox control, I just said to set the entire background color of the control to red and not just the border. Without any fancy forced triggering via Notify on Property Changed, if I swap between pages, the red background of the entire textbox remains constant.
Now, on to the combobox control. For those who have customized their own, or even looked into the default MS version of the control, its actually a clustered mess of controls, grids, columns, buttons, etc to make the magic of combobox work. In brief...
ControlTemplate
Grid (two columns, one for text display of chosen, second column for the drop-down arrow)
Border spanning both columns
Path ( line drawing / glyph for the drop-down image for combobox )
ControlTemplate TargetType Textbox (as part of the entire combobox set)
Border specifically "PART_ContentHost"
ControlTemplate of combobox
Grid
Toggle Button
Dropdown exposed showing list
other triggers..
Finally, the main ComboBox declaration which is templated by above components.
Anyhow, I can't for the life of me get this. In the "Toggle Button" area of the combobox declaration, I have a trigger to change the background to an OBVIOUS off color for proof of testing the trigger working and in the right location within the ControlTemplate declarations.
So, knowing this is the correct place within the combobox declarations, I want to supersede the green background color with red if there's an error with the data. I KNOW the overall "Validation.HasError" is properly getting triggered as the native error handler shows. No matter how / where within the template I try to change the background color to red, it does NOT work. I've even tried doing DataTriggers, using converters, trying multiple properties, but it appears not to be cooperating.
Any suggestions? This is getting really annoying.
FINALLY, got it... and not as obvious as I would have guessed. Anyhow, here's what I've found. If you went with a sample from Microsoft's template of the combobox, they first provide the overall two-column "ToggleButton" declaration
<ControlTemplate TargetType="ToggleButton"
x:Key="baseComboBoxToggleButton" >
... blah blah...
</ControlTemplate>
Then, the declaration for the "Display Value" of the combobox
<ControlTemplate TargetType="TextBox" x:Key="ComboBoxTextBox" >
<Border x:Name="PART_ContentHost" Focusable="False"
Background="{TemplateBinding Background}" />
</ControlTemplate>
Then, tie them together as one Combobox "wrapper" declaration
<ControlTemplate TargetType="ComboBox" x:Key="ComboBoxGridControlTemplate" >
<Grid x:Name="GridComboWrapper">
<!-- This is the dropdown button that POINTS TO THE "baseComboBoxToggleButton at the top -->
<ToggleButton Name="ToggleButton"
Template="{StaticResource baseComboBoxToggleButton}"
Grid.Column="2" Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press" >
</ToggleButton>
...
rest of the content presenter,
EDIT(able) textbox area,
popup area of combobox when in drop-down mode
</Grid>
<ControlTemplate.Triggers>
<!-- PUT THE VALIDATION CHECK HERE -->
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
<!-- THIS IS THE CRITICAL COMPONENT... I HAD TO EXPLICITLY TELL
The TagetName as the "ToggleButton" and change ITs Background property
and it now works -->
<Setter TargetName="ToggleButton" Property="Background"
Value="{StaticResource BrushDataInvalidBorder}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
So, now it works as intended and doesn't loose any adorner just because the active page on a given form changes and clears it... its static to each individual control as expected... Wow... what a PITA this one was.
Hope it helps someone ELSE in the future from excessive head banging against a wall while learning this nested level of stuff.

How to force zero pixel Gap between Consecutive Cells in WPF DataGrid

i am building an application in WPF for a custom need. First i opted for custom controls, but later on figured out that much of what i needed was already implemented in Datagrid Control. However there is one small glitch:
The problem with Datagrid is that it enforces a minimum of 2 pixel gap between two consecutive cells (1 on each side of the Grid Line). Please have a look at the following diagram for clarity:
.
Please note the 2 pixels gap enforced by the Datagrid between the two consecutive cells:
http://img265.imageshack.us/img265/3545/figurem.png
(Stack overflow wouldn't let me add image to my question citing a spam protection policy for new users)
.
This doesn't suit my requirement as i want the content to appear "continuous" (There must not be this gap of 2 pixels; i want the connecting lines to look "connected"). i've tried fidgeting with the GridLinesVisibility, but it didn't help. The DataGrid is hosting a custom control like this:
<DataGrid.Columns>
<DataGridTemplateColumn Width="25" Header="">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=MyCustomControl}" Margin="0"></ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
....
</DataGrid.Columns>
i have so far tried:
Switching off the GridLine (see result here: http://img263.imageshack.us/img263/8602/figure2j.png)
Setting the margin of the content property to 0.
Searched google and stackoverflow
Consulted some books.
but nothing seems to come up.
Is there a solution to this/some hack or a workaround or would i have to create everything from scratch? i have decent experience with c#, but i am new to WPF.
Please Help.
What you need to do is get at the DataGridCell style for your DataGrid and set its BorderThickness to be 0. It's hard-coded as 1 in the default style, but fortunately it's easy to override this:
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
</Style>
I would suggest putting that into the resources of your DataGrid so it only affects that one grid, unless you want it to have a wider scope than that.
<DataGrid>
<DataGrid.Resources>
<Style TargetType="DataGridCell">...</Style>
</DataGrid.Resources>
...
</DataGrid>
There are other places you could put it as well, depending on your precise needs.

WPF: How to implement custom Grid with CellSpacing?

I miss the HTML-cellspacing in WPF. Im trying to implement something similar in WPF's Grid by making a custom Grid-class overriding from Grid and then modifying MeasureOverride and ArrangeOverride to get the behaviour I want. Which is that each cell in a grid should have a fixed spacing (not padding) to each other cell. How could this be done?
I found this blog post about creating a custom grid panel that handles spacing between cells: http://daniel-albuschat.blogspot.dk/2011/07/gridlayout-for-wpf-escape-margin-hell.html
You could probably write your own panel, or perhaps even a Grid descendant, that does your own layout with cell spacing. It would be a fair bit of work.
Here's what I usually do instead, to achieve the same thing. Suppose I want a cell spacing of 3 pixels. You can accomplish that by applying a 1.5 pixel margin to each cell (so the total space between a cell and its neighbor is 1.5 + 1.5 = 3 pixels), and then another 1.5 pixel margin around the entire Grid so the outer margin is correct (1.5 pixel margin around the cell + 1.5 margin around the Grid = 3 pixels). The XAML looks like this:
<Grid Margin="1.5">
...
<Label Grid.Row="0" Grid.Column="0" Margin="1.5">...</Label>
<TextBox Grid.Row="0" Grid.Column="1" Margin="1.5">...</TextBox>
...
</Grid>
It's ugly but it works.
If most of the controls in your Grid are of the same type (e.g. if it's all Labels, or all Labels and TextBoxes), then you can use styles, instead of declaring and re-declaring the Margin on every element in the grid:
<Grid Margin="1.5">
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="Margin" Value="1.5"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="1.5"/>
</Style>
</Grid.Resources>
...
<Label Grid.Row="0" Grid.Column="0">...</Label>
<TextBox Grid.Row="0" Grid.Column="1">...</TextBox>
...
</Grid>
Actually, I've found in practice that I often want uneven margins -- for example, I may want a 3-pixel margin around the top, left, and right, but no margin on the bottom (because the controls below it already have a margin of their own). So I usually don't end up using 1.5 pixels all around; I usually end up with something more complex. So I can see why they didn't add a CellSpacing; it would make the simple cases simpler, but would be useless in more complicated layouts.
But half-margins-all-around is a quick way to achieve CellSpacing, and then you can tweak the margins if you need something fancier.
You may interested with my answer here, supports uniform border and cellspacing for each child in a custom grid:
How could I put a border on my grid control in WPF?
You're looking for the Margin property. You can style the DataGridCell class.
<Style TargetType="{x:Type toolkit:DataGridCell}">
<Setter Property="Margin" Value="3" />
</Style>

WPF Style Trigger

I change the FontSize of Text in a Style trigger, this causes the Control containing the text to resize as well. How can I change the Fontsize without affecting the parent's size?
A nice trick to isolate an element from its parent layout wise is to place the element in a Canvas
In the markup below there are two copies of your element
The first is hidden and establishes the size of your control
The second is visible but wrapped in a Canvas so its layout size does not affect the parent.
<Parent>
<Grid>
<Element Visibility="Hidden"/>
<Canvas>
<Element />
</Canvas>
<Grid>
</Parent>
You can increase the Padding at the same time you decrease the FontSize - this will cause the calculated height of the Button to remain the same:
<StackPanel>
<Button Content="ABC">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="20"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Padding" Value="5"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Margin="0,20" Content="123" FontSize="20"/>
<Button Content="Do Re Mi" FontSize="20"/>
</StackPanel>
You can do the reverse and set a negative Padding if the FontSize is increasing, as well.
You could also use a binding from FontSize to Padding to accomplish the same thing in a general way, but if you're only dealing with a fixed set of FontSizes it would be easier to just hardcode it as above.
There is absolutely NO need for hard-coded widths, crazy measure overrides, tricky bindings, or anything of that sort.
The solution is actually incredibly simple. Instead of changing the font size in a style trigger, create a simple control template for your button with a RenderTransform applied to the content presenter element. Add a ScaleTransform to the RenderTransform. Inside a IsPressed trigger definition set the vertical and horizontal scales on the ScaleTransform to a smaller ratio, say 0.8.
Using a RenderTransform will keep the layout of the pressed button the same with, so it won't influence the position of the other elements. By contrast, using a LayoutTransform would have actually caused the button container to shrink and the parent container's ArrangeOverride method would cause the adjacent buttons to move to fill the extra space.
I'm really busy right now so I'll leave the actual implementation up to you! ;-)
http://msdn.microsoft.com/en-us/library/system.windows.media.scaletransform.aspx
I am creating a ControlTemplate for a ButtonControl so it looks like a label (flat text, no borders) with triggers for IsKeyboardFocused, IsPressed, IsDefaulted etc.
The IsPressed is defined to drop the FontSize (from default of 30) down to 28. To give a pressed animation effect.
One use of these Buttons is a horizontal StackPanel of Button, separated by vertical separators. When the IsPressed trigger is fired on a button and it is resized, the entire row of buttons gets re adjusted, which is not a pleasing visual effect.
My preference is for a template based solution, to avoid introducing new controls in order to provide overrides. The only problem with the hard coded size approach is internationalisation, other languages will increase the orginal size.
The solution I am going with is to set the minWidth in C# after the button's DesiredSize has been calculated. Note that Width is NaN even after the Button is rendered hence the use/existence of DesiredSize. Later I will try and XAMLize the C#.
What kind of control are you using? If this is a HeaderedControl like a GroupBox or TabItem then you need to specifically set the HeaderTemplate like this:
<DataTemplate x:Key="MyHeaderTemplate">
<TextBlock Text="{Binding}" Fontsize="14" FontWeight="Bold" />
</DataTemplate>
I can think of a couple of things you could try:
You can override the Measure Pass of the control - when a control is rendered in WPF it undergoes two passes. The first is a 'measure pass', where the control comes up with what sizes that it wants to be. The second is the 'arrange pass', where it actually lays out the control. WPF provides a method called MeasureOverride. If you override this method you can provide custom behavior that can be used to adjust the size of the control.
Note - I believe that you will have to call the Measure method all of your controls children during this override in order to get your control to lay out properly.
Hard code the height and width on the control - this will override the control's DesiredSize with your values. While generally a not the greatest of ideas, it will work.

Resources