Keeping Canvas overflow in WPF - wpf

I have a (hopefully) interesting question.
First of all what I'm trying to do here:
I'm trying to create a pie-chart-like set of buttons, later this control will be used within a touch enabled application. The control draws and looks just fine, also all of the behaviours are fine so far. However, one thing that I'm having issues with is the translations I do to all the pieces of the pie.
SO what I do is: I want margin n between the pie pieces, to create this margine I move all pieces away from the middle. This means that the pie piece that's facing UP will have a negative translation. This in turn means that the Canvas will clip a part of the top (due the top being at 14, -2 for example). Another thing that I've added are pieces of text which are also making the pie pieces quite a bit longer. See the image included for reference.
image
To the left you can see the clipping issue I'm talking about to the right you can see an arbitrarily translated version of the same thing.
Some code paste:
Main window XAML:
<controls:PieMenu Radius="100" Padding="10">
<controls:PieMenu.MenuItems>
<controls:PieMenuItem Text="Employment" Brush="#FF33FF" Command="BrowseBack" />
<controls:PieMenuItem Text="General" Brush="#9933FF" Command="BrowseBack" />
<controls:PieMenuItem Text="Internships" Brush="#3333FF" Command="BrowseBack" />
<controls:PieMenuItem Text="Bla" Brush="#3399FF" Command="BrowseBack" />
<controls:PieMenuItem Text="Bla" Brush="#007AF5" Command="BrowseBack" />
</controls:PieMenu.MenuItems>
PieMenu XAML:
<UserControl x:Class="PieControlLibrary.PieMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:self="clr-namespace:PieControlLibrary"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<!-- <CollectionViewSource x:Name="menuItemCollectionViewSource" Source="{Binding MenuItems, RelativeSource={RelativeSource AncestorType=self:PieMenu}}"/>-->
<Style TargetType="{x:Type ListView}" x:Key="listViewStyle">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<self:PieButton Radius="{Binding Radius, RelativeSource={RelativeSource AncestorType=self:PieMenu}}"
Degrees="{Binding Degrees, RelativeSource={RelativeSource AncestorType=self:PieMenu}}"
Brush="{Binding Brush}"
Command="{Binding Command}"
Text="{Binding Text}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<ListView x:Name="menuItemsView" ItemsSource="{Binding MenuItems, RelativeSource={RelativeSource AncestorType=self:PieMenu}}" Style="{StaticResource listViewStyle}" />
</Grid>
PieButton (this is what the pie menu items are converted to)
<UserControl x:Class="PieControlLibrary.PieButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:control="clr-namespace:PieControlLibrary"
xmlns:TextOnPath="clr-namespace:Petzold.TextOnPath"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
>
<Grid>
<Button HorizontalAlignment="Left" VerticalAlignment="Top" DataContext="{Binding RelativeSource={RelativeSource AncestorType=control:PieButton}}" Command="{Binding Command}">
<Button.Template>
<ControlTemplate>
<Canvas >
<Path Data="{Binding PathData}" Fill="{Binding Brush}" Grid.Row="0" Grid.Column="0" />
<TextOnPath:TextOnPathControl PathFigure="{Binding TextPath}" Text="{Binding Text}" FontFamily="Consolas" FontSize="12" Foreground="Black" FontStretch="Normal" />
</Canvas>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>

I'm not sure if I understand your question, but when you draw your pie chart, just leave some extra space around the edges so you can move the pie pieces out from the center?

Perhaps you could use a RenderTransform when your pie pieces expand to shift or scale the image a tiny bit to keep it in bounds?

Related

WPF: Is there a reliable way to port argb values of Brushes to rgba color values of web browsers?

Lately I found out that it seems to matter a lot where "Opacity" is set in WPF:
Option 1: By setting Brush Color with #ARGB
Option 2: By setting Opacity as Property of Brush
Option 3: By setting Opacity directly on the Control
Screenshot of results:
Different ways to produce opacity
While options 1 & 2 appear to produce the same results, option 3 seems to be similar to what web browsers produce.
Now my question is, can opacity values set on brushes (WPF) somehow be converted to opacity values of "color" in web browsers? Because setting a control´s opacity seems not the best way to go for "coloring" layout elements.
Here´s the XAML layout which produces the output as described & shown above:
<Window x:Class="Color_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Color_Test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<SolidColorBrush x:Key="Brush_Test_Bg" Color="#25252B" />
<SolidColorBrush x:Key="Brush_Test_Fg_OpacityByArgb" Color="#5cffffff" />
<SolidColorBrush x:Key="Brush_Test_Fg_OpacityByPropertyOnBrush" Color="#ffffff" Opacity=".36"/>
<SolidColorBrush x:Key="Brush_Test_Fg_OpacityByPropertyOnControl" Color="#ffffff"/>
</ResourceDictionary>
</Window.Resources>
<Grid Background="{StaticResource Brush_Test_Bg}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="1: Opacity by Brush Color='#5cffffff'" FontSize="24" FontWeight="Bold" Foreground="{StaticResource Brush_Test_Fg_OpacityByArgb}" />
<TextBlock Text="2: Opacity by Brush Color='#ffffff' and Brush Opacity='.36'" FontSize="24" FontWeight="Bold" Foreground="{StaticResource Brush_Test_Fg_OpacityByPropertyOnBrush}" />
<TextBlock Text="3: Opacity by Brush Color='#ffffff' and TextBlock Opacity='.36'" FontSize="24" FontWeight="Bold" Foreground="{StaticResource Brush_Test_Fg_OpacityByPropertyOnControl}" Opacity=".36" />
</StackPanel>
</Grid>
Also, here´s a Codepen-Link to the web-output for comparison.
For completion: I tried TextOptions.TextFormattingMode="Display" inside the wpf layout which produces only different (uncontrollable) results.

Wpf app with AvalonDock docking layout system

I am creating a small wpf program in .net5. It should have a tab system and a sidebar. The Dirkster.AvalonDock library github is suitable for my purposes. Installed version 4.60.0. I just started getting to know this library. The difficulty arose with the sidebar. LayoutAnchorablePane is responsible for its output. But the result is not what I expect.
I need to get something like this
img1
There is now
img2
View code:
<Window x:Class="TestApp.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:TestApp.ViewModels"
xmlns:cm="http://www.caliburnproject.org"
mc:Ignorable="d"
Width="800" Height="450"
Title="MainWindow">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<DockingManager x:Name="DockManager" Grid.Column="0"
DocumentsSource="{Binding Items}"
AnchorablesSource="{Binding MenuItems}"
>
<DockingManager.LayoutItemTemplate>
<DataTemplate>
<ContentControl cm:View.Model="{Binding Content}" IsTabStop="False" />
</DataTemplate>
</DockingManager.LayoutItemTemplate>
<DockingManager.LayoutItemContainerStyle>
<Style TargetType="{x:Type LayoutItem}">
<Setter Property="Title" Value="{Binding Model.DisplayName, Mode=OneWay}"/>
<Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}"/>
</Style>
</DockingManager.LayoutItemContainerStyle>
<LayoutRoot>
<LayoutPanel>
<LayoutDocumentPaneGroup>
<LayoutDocumentPane />
</LayoutDocumentPaneGroup>
<LayoutAnchorablePaneGroup>
<LayoutAnchorablePane DockMinWidth="300" />
</LayoutAnchorablePaneGroup>
</LayoutPanel>
</LayoutRoot>
</DockingManager>
</Grid>
The viewmodel code is not important, I think. Also installed in the project is caliburn.micro
Please tell me how to get the sidebar as in the first picture.
You have to install VS2013 theme package (link) then use the light version like the following:
<DockingManager.Theme>
<Vs2013LightTheme />
</DockingManager.Theme>

Scrollbars not visible + Events not thrown

I would like to implement a userControl which is able to scroll and zoom with provided mouse input.
Therefore, I implemented following user Control. (If its working I am going to move the Events directly to the Model)
ScrollDragZoomControl.xaml
<UserControl x:Class="MinimalMonitoringClient.Controls.ScrollDragZoomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:models="clr-namespace:MinimalMonitoringClient.Controls.Models"
Background="Transparent">
<UserControl.DataContext>
<models:ScrollDragZoomViewModel />
</UserControl.DataContext>
<ScrollViewer x:Name="scrollViewer"
MouseLeftButtonUp="scrollViewer_MouseLeftButtonUp"
PreviewMouseLeftButtonUp="scrollViewer_PreviewMouseLeftButtonUp"
PreviewMouseWheel="scrollViewer_PreviewMouseWheel"
PreviewMouseLeftButtonDown="scrollViewer_PreviewMouseLeftButtonDown"
MouseMove="scrollViewer_MouseMove"
VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility}"
HorizontalScrollBarVisibility="{Binding HorizontalScrollBarVisibility}">
<Grid RenderTransformOrigin="0.5,0.5">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform />
</TransformGroup>
</Grid.LayoutTransform>
<Viewbox>
<!-- Present the actual stuff the user wants to display -->
<ContentPresenter />
</Viewbox>
</Grid>
</ScrollViewer>
In another UserControl I would like to use this UserControl so show Content which could be bigger than the current UserControl's width and height. For Testing I set Width and Height to something huge.
<UserControl x:Class="MinimalMonitoringClient.Panels.HierarchicalView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:panels="clr-namespace:MinimalMonitoringClient.Models.Panels"
xmlns:controls="clr-namespace:MinimalMonitoringClient.Controls">
<UserControl.DataContext>
<panels:HierarchicalViewModel />
</UserControl.DataContext>
<controls:ScrollDragZoomControl>
<Image Source="/Images/Information.png" Width="2000" Height="2000" IsHitTestVisible="False" />
</controls:ScrollDragZoomControl>
No Events are called in the ScrollDragZoomControl. I set the
Background to transparent. Also played with IsHitTestVisible.
The Scrollbars are not visible.
When you set the Content property of the UserControl to an Image element you effectively "override" any content that you have defined in ScrollDragZoomControl.xaml.
You probably want the ScrollViewer and the rest of the stuff you have defined in ScrollDragZoomControl.xaml to be part of the UserControl's template:
<UserControl x:Class="MinimalMonitoringClient.Controls.ScrollDragZoomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:models="clr-namespace:MinimalMonitoringClient.Controls.Models"
Background="Transparent">
<UserControl.DataContext>
<panels:HierarchicalViewModel />
</UserControl.DataContext>
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<ScrollViewer x:Name="scrollViewer"
MouseLeftButtonUp="scrollViewer_MouseLeftButtonUp"
PreviewMouseLeftButtonUp="scrollViewer_PreviewMouseLeftButtonUp"
PreviewMouseWheel="scrollViewer_PreviewMouseWheel"
PreviewMouseLeftButtonDown="scrollViewer_PreviewMouseLeftButtonDown"
MouseMove="scrollViewer_MouseMove"
VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility}"
HorizontalScrollBarVisibility="{Binding HorizontalScrollBarVisibility}">
<Grid RenderTransformOrigin="0.5,0.5">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform />
</TransformGroup>
</Grid.LayoutTransform>
<Viewbox>
<!-- Present the actual stuff the user wants to display -->
<ContentPresenter />
</Viewbox>
</Grid>
</ScrollViewer>
</ControlTemplate>
</UserControl.Template>
</UserControl>

wfp charting toolkit: show data point values above all columns

total emergency here. Just saw WPF for the first time and need this quick, so forgive me: if I don't provide enough info first time around I promise to edit the question.
In a charting object, defined with namespace:
xmlns:charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
I am drawing a simple bar chart.
<charting:Chart Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"
Visibility="{Binding Path=MyCurrentResultsView, Converter={StaticResource ResourceKey=NullObjectToVisibilityConverter}}"
Background="Transparent" Foreground="White"
Margin="50,0,50,0" Height="350"
HorizontalAlignment="Stretch" Title="{Binding Path=MyCurrentResultsView.Name}">
<charting:ColumnSeries Height="350" Foreground="Black"
ItemsSource="{Binding Path=MyCurrentResultsView.ResultsView}"
IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}">
</charting:ColumnSeries>
</charting:Chart>
What I'd like to do is to show the value of each column above the column (or even inside the column rectangle if possible: these are percentage values and the idea is to make them more visible on the bar chart).
I have been looking at the styling information, but here this is more than just style. I see two possibilities. Either:
For each column item in the series, define a transformation that positions a frame above each column, creates a text box whose label is set to the dependent value, then draws the text box inside the frame.
Find some kind of property on "ColumnSeries" or "? ColumnItem ?" that "enables" the display of the bound value above the column.
Total shot in the dark here. Thanks.
I would try to change the ColumnDatapointTemplate like this:
<charting:ColumnSeries Height="350" Foreground="Black"
ItemsSource="{Binding Path=MyCurrentResultsView.ResultsView}"
IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}">
<charting:ColumnSeries.DataPointStyle>
<Style TargetType="charting:ColumnDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="charting:ColumnDataPoint">
<Grid>
<Rectangle Fill="{TemplateBinding Background}" Stroke="Black"/>
<Grid Margin="0 -20 0 0" HorizontalAlignment="Center" VerticalAlignment="Top">
<TextBlock Text="{TemplateBinding FormattedDependentValue}" Margin="2"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</charting:ColumnSeries.DataPointStyle>
</charting:ColumnSeries>
Play a bit with vertical alignments and/or margins and you will be able to get infos into the columns and other.
Hope this help!

How to fit TextBlock size to text size

i am working in silverlight for embedded windows and i want to fit text to the TextBlock as seen on picture, i want textBlock to fit text ( i want to remove yelow space in attached picture )
Can someone help me with this?
Best regards,
Luka
Here is the XAML i am currently using:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="FullTest.PUIsocUI"
d:DesignWidth="480" d:DesignHeight="272">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Height="64" Grid.Row="1">
<RadioButton x:Name="PowerMeasurement" GroupName="PowerTabControls" IsChecked="True" Checked="PowerMeasurement_Checked" Unchecked="PowerMeasurement_Unchecked" Content="POWER" BorderThickness="0"/>
<RadioButton x:Name="PowerMode" GroupName="PowerTabControls" Checked="PowerMode_Checked" Unchecked="PowerMode_Unchecked"/>
<RadioButton x:Name="PowerLimit" GroupName="PowerTabControls" IsChecked="False" Click="PowerLimit_Click" Checked="PowerLimit_Checked" Unchecked="PowerLimit_Unchecked"/>
</StackPanel>
<Grid>
<Grid x:Name="PowerMeasurementPage" Margin="0,0,0,64" >
<!-- tab page za meritev-->
<TextBlock Text="POWER" Style="{StaticResource FunctionNameTextBlockStyle}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock Text="11.555" Style="{StaticResource ResultNameTextBlockStyle}" />
</Grid>
<Grid x:Name="PowerModePage" Margin="0,0,0,64">
<!-- tab page za Mode-->
</Grid>
<Grid x:Name="PowerLimitPage" Margin="0,0,0,64">
<!-- tab page za Limita-->
</Grid>
</Grid>
</Grid>
<Style TargetType="TextBlock" x:Key="FunctionNameTextBlockStyle">
<Setter Property="FontFamily" Value="ALTERNATE_GOTHIC#AlternateGothic2 BT"/>
<Setter Property="FontSize" Value="44"/>
<Setter Property="Margin" Value="57,27,0,0"/>
</Style>
this is what i want to get ->
<TextBlock Text="POWER" FontSize="44" FontWeight="SemiBold" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<CompositeTransform ScaleY="2"/>
</TextBlock.RenderTransform>
</TextBlock>
In the example I've provided see the ScaleY declaration? Adjust that value to meet your needs. That's one way to accomplish that effect without using ViewBox. Another might be to convert that TextBlock in to a Path and adjust as necessary also, but it would have to be a static label for that to be useful.
Hope this helps! :)
The other way is even much simpler. You just have to let TextBlock to resize itself, it will arrange itself based on text. You should look into its container probably (probably paste some code?). Try setting TextBlock like this:
<TextBlock Text="POWER" HorizontalAlignment="Center" VerticalAlignment="Center" />
UPDATE look into VS, to me it seems that it is just a font reserved space. Not sure how you can avoid that.
In VS2015 you can do this easily with TextLineBounds property (set it to Tight in your case). I use it in UAP, not sure it's available in Silverlight. However it gets truncated for lowercase letters like g, q, etc as posted here: TextLineBounds snipping bottom of letters

Resources