Set xaml icon in fluentribbon button - c#

I use fluentribbon and mahapps for my GUI and want to have a button in my ribbon with a icon. I want to use xaml icons like this (not a file). So i need to set Path in the fluent:Button. I tried the following but its not working - Button is
blank (no text and no icon shown):
<fluent:Button Name="Test">
<StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Center">
<Path Width="40" Height="40" Stretch="Uniform" UseLayoutRounding="False" Fill="Black" Data="..."/>
<TextBlock><Run Text="Test Button"/></TextBlock>
</StackPanel>
</fluent:Button>
Update
Here is the complete code:
<Controls:MetroWindow x:Class="RibbonTestProj.View.RibbonTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:fluent="urn:fluent-ribbon"
Title="Ribbon Test" Height="474" Width="849" MinHeight="300" MinWidth="400" >
<Grid>
<fluent:Ribbon CanMinimize="False" CanQuickAccessLocationChanging="False" AutomaticStateManagement="false"
x:Name="ribbon">
<fluent:RibbonTabItem x:Name="test1TabItem"
Header="Test1"
KeyTip="I">
<fluent:RibbonGroupBox Header="Group1" Height="84" Width="248" TabIndex="0">
<fluent:Button Name="Test">
<StackPanel VerticalAlignment="Stretch"
HorizontalAlignment="Center">
<Path Width="40"
Height="40"
Stretch="Uniform"
Fill="Black"
Data="M 10,100 C 10,300 300,-200 300,100" />
<TextBlock><Run Text="Test Button" /></TextBlock>
</StackPanel>
</fluent:Button>
</fluent:RibbonGroupBox>
<fluent:RibbonGroupBox Header="Group2" VerticalAlignment="Stretch" Height="84" Width="98" TabIndex="1">
</fluent:RibbonGroupBox>
</fluent:RibbonTabItem>
<fluent:RibbonTabItem x:Name="test2TabItem"
Header="Test2"
KeyTip="O">
</fluent:RibbonTabItem>
</fluent:Ribbon>
</Grid>
</Controls:MetroWindow>
and here how it looks like (the Button is there and i can click on it but there is no text and no icon)

Sorry for the late response. It took me some time to get the library running. It seems that you could set the LargeIcon
<fluent:Button Name="Test">
<fluent:Button.LargeIcon>
<Path Width="40"
Height="40"
Stretch="Uniform"
Fill="Black"
Data="M 10,100 C 10,300 300,-200 300,100" />
</fluent:Button.LargeIcon>
Test Button 1
</fluent:Button>
Don't forget: You can always extract a Controls default template. You can than look up how the control is build inside. How to Extract Default Control Template In Visual Studio?

Related

Display icon over select images in wpf listbox

I've looked at some related answers (Content of a Button Style appears only in one Button instance, and Images only showing in last ListBoxItem), but can't seem to get their answers to work in my example.
My app wpf stack is relatively complex.
I've a UserControl within another window. Within the UserControl, I've a ListBox with nested elements ListBox.ItemTemplate > DataTemplate > Border > Grid > StackPanel
Within the StackPanel is a TextBlock, followed by an Image and a StackPanel.ToolTip
I'm wanting to place an icon over the Image, so I've further obfuscated the image by putting it in a Grid, and adding a ViewBox accessed via a Control Template (as suggested in the above links), so that the ViewBox is centered on the image. Here's the Grid:
<Grid>
<Image RenderOptions.BitmapScalingMode="HighQuality"
Height="{Binding ElementName=_this, Path=ThumbSize.Height}"
>
<gif:ImageBehavior.AnimatedSource>
<MultiBinding Converter="{c:ImageConverter}">
<Binding Path="ThumbLocation" />
<Binding Path="FullName" />
</MultiBinding>
</gif:ImageBehavior.AnimatedSource>
</Image>
<Control Template="{StaticResource PlaySymbol}" Visibility="{Binding PlayVisible}" />
</Grid>
The ViewBox's ControlTemplate is in the UserControl.Resources up at the top
<ControlTemplate x:Key="PlaySymbol" TargetType="{x:Type Control}">
<Viewbox Stretch="Uniform"
RenderTransformOrigin="0.5,0.5"
Opacity="0.75"
x:Shared="False"
>
<Viewbox.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
</TransformGroup>
</Viewbox.RenderTransform>
<ContentControl Content="{StaticResource appbar_control_play}" />
</Viewbox>
</ControlTemplate>
The appbar_control_play is in the Resources directory in an Icons.xaml file.
<Canvas x:Key="appbar_control_play" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="20.5832" Height="31.6667" Canvas.Left="30.0833" Canvas.Top="22.1667" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 30.0833,22.1667L 50.6665,37.6043L 50.6665,38.7918L 30.0833,53.8333L 30.0833,22.1667 Z "/>
</Canvas>
The goal is to only display the icon for 'play' on movies. I've set the PlayVisible to return the proper visibility for movies, and not for other files. Yet, it is only displaying for the last movie. I've heard that this is the case for controls only able to have one parent. I've tried setting x:Shared="False" on the ViewBox, but to no avail.
The app works, but I've recently decided to add movies to the listing and want to display the play icon over their thumbnails, but not the other items. It seems simple on the outset, but I've yet to figure out what is needed.
Any help would be appreciated, otherwise I feel I may have to resort to overlaying the icon on the actual thumbnails of the movies.
It looks like the problem is not related to the Viewbox but the image resource appbar_control_play it references.
There is no need to add the Viewbox via a Control. Just add it directly to the DataTemplate.
Generally prefer a ContentControl over a templated Control if you wish to display content.
The x:Shared attribute is only required on a UIElement that is not part of a template but defined in a ResourceDictionary. For example, when you define the Viewbox in as a resource, you must set the x:Shared attribute to false. Otherwise it is only allowed to appear once in the visual tree.
In case the image resource is an image file, a proper DataTemplate could look as followed:
<DataTemplate>
<StackPanel>
<Grid>
<Image Source="path to image" />
<Image Source="path to overlay icon"
Stretch="UniformToFill"
Width="50"
Height="50" />
</Grid>
</StackPanel>
</DataTemplate>
In case the icon is a XAML resource like a Geometry or a Segoe MDL2 Assets font icon, the DataTemplate should look as followed:
App.xaml
<Application.Resources>
<Viewbox x:Key="PlayIcon" x:Shared="False">
<TextBlock FontFamily="Segoe MDL2 Assets"
Text="" />
</Viewbox>
<Viewbox x:Key="appbar_control_play"
x:Shared="False">
<Path Width="20.5832"
Height="31.6667"
Stretch="Fill"
Fill="{Binding RelativeSource={RelativeSource AncestroType=ContentControl}, Path=For4ground}"
Data="F1 M 30.0833,22.1667L 50.6665,37.6043L 50.6665,38.7918L 30.0833,53.8333L 30.0833,22.1667 Z " />
</Viewbox>
</Application.Resources>
MyControl.xaml
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<Image Source="path to image" />
<ContentControl Content="{StaticResource appbar_control_play}"
Width="50"
Height="50"
Foreground="Pink" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Not sure what's happening on your side but the following just works:
<Window x:Class="abc.Window1"
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:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="d"
Title="Window1">
<Grid>
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</DataTemplate.Resources>
<Border Width="64" Height="64" BorderBrush="Red" BorderThickness="1">
<Grid>
<TextBlock Text="{Binding}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<Rectangle Fill="DeepSkyBlue"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="2"
Width="16"
Height="16"
Visibility="{Binding Converter={StaticResource BooleanToVisibilityConverter}}"
x:Name="Button" />
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<system:Boolean>True</system:Boolean>
<system:Boolean>False</system:Boolean>
<system:Boolean>True</system:Boolean>
<system:Boolean>False</system:Boolean>
<system:Boolean>True</system:Boolean>
<system:Boolean>False</system:Boolean>
</ListBox>
</Grid>
</Window>

How to get a not selected item from wpf's listview

I'm working on a image displayer and I custom a datatemplate of listview(it's the images container) with two overlapping button to show the image is liked or disliked, and I need to do something when I click them, but I found that the item won't be selected if I just click the button, this makes I cannot get the item of the button which i clicked
I've try to google it but there's no help, all answers I got need to get the selecteditem at first, but this is where the question is
this is my data template
<DataTemplate DataType="model:PictureViewModel">
<Grid x:Name="ImageContentPresenter" Width="150" Height="150">
<Border x:Name="Border1" CornerRadius="15" Background="#FAFAFC" />
<Grid Height="150" Width="150">
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Border1}" />
</Grid.OpacityMask>
<Border Background="#FAFAFC" x:Name="ImageCornerBorder"
CornerRadius="15,15,15,15" />
<Image x:Name="DisplayedImage" Stretch="Uniform"
Source="{Binding Path=ImageSource,Mode=OneWay,Converter={StaticResource BitmapImageConverter}}"
Loaded="DisplayedImage_OnLoaded">
<Image.OpacityMask>
<VisualBrush Visual="{Binding ElementName=ImageCornerBorder}" />
</Image.OpacityMask>
</Image>
<Grid HorizontalAlignment="Right" VerticalAlignment="Top" Width="30"
Height="30" Margin="0,10,10,0">
<Grid.Resources>
<util1:VisibilityConverter x:Key="VisibilityConverter" />
<mainWindow:ButtonType x:Key="LikeButtonType">Like</mainWindow:ButtonType>
<mainWindow:ButtonType x:Key="DisLikeButtonType">DisLike</mainWindow:ButtonType>
</Grid.Resources>
<Button x:Name="LikeButton" Style="{DynamicResource MaterialDesignToolButton}" Visibility="{Binding IsLiked,Converter={StaticResource VisibilityConverter},ConverterParameter={StaticResource LikeButtonType}}" Click="LikeButton_OnClick">
<Viewbox Width="24" Height="24">
<Canvas Width="24" Height="24">
<Path
Data="M12.1,18.55L12,18.65L11.89,18.55C7.14,14.24 4,11.39 4,8.5C4,6.5 5.5,5 7.5,5C9.04,5 10.54,6 11.07,7.36H12.93C13.46,6 14.96,5 16.5,5C18.5,5 20,6.5 20,8.5C20,11.39 16.86,14.24 12.1,18.55M16.5,3C14.76,3 13.09,3.81 12,5.08C10.91,3.81 9.24,3 7.5,3C4.42,3 2,5.41 2,8.5C2,12.27 5.4,15.36 10.55,20.03L12,21.35L13.45,20.03C18.6,15.36 22,12.27 22,8.5C22,5.41 19.58,3 16.5,3Z"
Fill="Gray" />
</Canvas>
</Viewbox>
</Button>
<Button x:Name="DislikeButton" Style="{DynamicResource MaterialDesignToolButton}" Visibility="{Binding IsLiked,Converter={StaticResource VisibilityConverter},ConverterParameter={StaticResource DisLikeButtonType}}">
<Viewbox Width="24" Height="24">
<Canvas Width="24" Height="24">
<Path
Data="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
Fill="Crimson" />
</Canvas>
</Viewbox>
</Button>
</Grid>
</Grid>
</Grid>
</DataTemplate>
the LikeButton and DislikeButton are those two buttons, how exactly can I get the item where i clicked button is
You could access PictureViewModel object by accessing the DataContext property on the Button object in your LikeButton_OnClick method.
The ideal way would be to use Commands. You could have LikeCommand defined on the PictureViewModel itself and access it via this from the Command Handler.

Detect if TextBlock is visible in StackPanel

I have a StackPanel with a variable height based on available screen height/resolution, and I need to fill it up with data. The tricky part is my data is very dynamic and has headers/areas with different margins so doing a simple show x items isn't reliable.
Is there a way to detect if a TextBlock is completely visible inside a StackPanel? I'd like to not have half cut off items displayed if possible.
So this is more complicated than you are probably considering. That's because there's a lot of work to determine if there is something in front of an item. However, at its simplest, to determine if an item is visible on the screen you can use this technique.
Using this XAML:
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Grid x:Name="MyGrid">
<StackPanel x:Name="MyStackPanel" Orientation="Horizontal" Background="Gray">
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
</StackPanel>
</Grid>
</ScrollViewer>
Use this code behind:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
foreach (var item in MyStackPanel.Children.OfType<Windows.UI.Xaml.Shapes.Rectangle>())
{
// the box around the child
var _ItemBounds = item.TransformToVisual(null).TransformBounds(new Rect(0, 0, item.ActualWidth, item.ActualHeight));
// the box around the screen
var _Intersection = Window.Current.Bounds;
_Intersection.Intersect(_ItemBounds);
if (_Intersection.Equals(_ItemBounds))
// full
item.Fill = new SolidColorBrush(Windows.UI.Colors.Green);
else if (_Intersection.Equals(Rect.Empty))
// none
item.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
else
// partial
item.Fill = new SolidColorBrush(Windows.UI.Colors.Orange);
}
}
Hope that makes sense. I always prefer examples of explanations. When you run this, visible boxes are colored green, partials are orange, and out of bounds items are painted red. Pretty simple.
related: https://stackoverflow.com/a/1517794/265706

How create this wpf toolbar

I would like to create a toolbar like this on wpf.
What i need to use in order to create the area with the button circled in red ?
Is it possible with the microsoft toolbar ?
For the moment i tried this :
Here is my xaml code :
<ToolBarTray Background="#008ede" HorizontalAlignment="Stretch" VerticalAlignment="Top" Height="33" >
<ToolBar ToolBarTray.IsLocked="True" Background="#008ede" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center">
<Button Name="tbrClear" ToolTip="Clear" VerticalAlignment="Center">
<Image Source="_XWPF_TBR_PREMIER.PNG_IMAGES.png" Name="Image1"></Image>
</Button>
<Button Name="tbrClear_" ToolTip="Clear" VerticalAlignment="Center" VerticalContentAlignment="Center">
<Image Source="_XWPF_TBR_PRECED.PNG_IMAGES.png" Name="Image2"></Image>
</Button>
</ToolBar>
</ToolBarTray>
1) First, i would like to know how centered the button, i add the verticalAlignment="Center", but nothing is center. Have you an idea please?
2) Secondly, how remove or hide the little rectangle white on the right please ?
3) Then, anyone know how it's possible to recreate the area circled on red please ?
Thanks a lot :)
Best regards
Your tool bar looks centered. do you mean you want the toolbar to be where the caption/title is or do you want to hide the caption title? for the latter you can try WindowStyle="None" in your window.
As for for the 'little rectangle" try getting and setting OverflowGrid visibility property of the toolbar.
you probably also need to wrap the elments in aborder and use the corner radius to achieve the rounded corners. here's an example:
<DockPanel Height="40" VerticalAlignment="Top">
<Border BorderBrush="LightBlue" BorderThickness="1" CornerRadius="8" Margin="1" Background="#008ede">
<ToolBarTray Background="#008ede" HorizontalAlignment="Left" VerticalAlignment="Center" >
<ToolBar ToolBarTray.IsLocked="True" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center">
<Button Name="tbrClear" ToolTip="Clear" VerticalAlignment="Center">
<Image Source="_XWPF_TBR_PREMIER.PNG_IMAGES.png" Name="Image1"></Image>
</Button>
<Button Name="tbrClear_" ToolTip="Clear" VerticalAlignment="Center" VerticalContentAlignment="Center">
<Image Source="_XWPF_TBR_PRECED.PNG_IMAGES.png" Name="Image2"></Image>
</Button>
</ToolBar>
</ToolBarTray>
</Border>
</DockPanel>

Recolor region of image in C#

I'm working on building a diagnostic reader for my car. I can parse the messages from my OBD port but I want to create a display that is better than just a text readout. I want a graphical display of my car that will highlight the affected areas of the diagnostics. So if the tire pressure is low I want the tires on a picture of the car to turn red. I want to develop this in C# since that is what I'm the most familiar with. Any suggestions on what might be the best way to do this? It would also be nice if the method scaled with resizing the window.
<Image x:Name ="Bubble" Height="445" HorizontalAlignment="Left" Margin="42,12,0,0" Stretch="Fill" VerticalAlignment="Top" Width="654" Source="/WpfApplication1;component/Images/bubble.png" Panel.ZIndex="0" Opacity="1"/>
<Image x:Name="Smiley" Height="445" HorizontalAlignment="Left" Margin="42,12,0,0" Stretch="Fill" VerticalAlignment="Top" Width="654" Source="/WpfApplication1;component/Images/bubble.png" Panel.ZIndex="1" Opacity="0"/>
<Button Content="Button" Height="35" HorizontalAlignment="Left" Margin="10,46,0,0" Name="button1" VerticalAlignment="Top" Width="24" Click="button1_Click" />
<Button Content="Button" Height="50" HorizontalAlignment="Left" Margin="14,118,0,0" Name="button2" VerticalAlignment="Top" Width="22" Click="button2_Click" />
And then to change the opacity.
Bubble.Opacity = 0.0;
Smiley.Opacity = 1.0;
One way of doing this is having multiple images, and fading the opacity. You just need to make sure the image format supports transparency (png-s do nicely). Let's say you have a car image, and separate overlays for front and rear wheel. Keeping all images the same size for easy alignment.
You'll get something like
<Image x:Name="car" Source="car.png" Panel.ZIndex="0"/>
<Image x:Name="frontwheel" Source="frontwheel.png" Panel.ZIndex="1" Opacity="0"/>
<Image x:Name="rearwheel" Source="readwheel.png" Panel.ZIndex="2" Opacity="0"/>
Then in the code
frontwheel.Opacity=1.0;
Edit: here's a snippet from some code of mine. I add graphics to the canvases in the code-behind
<Grid Margin="20">
<Image Name="image1" Width="640" Height="640"
Opacity="{Binding Path=Value, ElementName=OpSlider}"
HorizontalAlignment="Center"
/>
<Canvas Name="MarkerLayer"
Opacity="{Binding Path=Value, ElementName=DotOverlaySlider}"
/>
<Canvas x:Name="Squares"
Opacity="{Binding Path=Value, ElementName=OverlayOpSlider}"
/>
</Grid>
Opacity here is bound to sliders
<Slider x:Name="OpSlider" Width="150" SmallChange="0.05" Maximum="1" Value="0.5" />
<Slider x:Name="OverlayOpSlider" Width="150" SmallChange="0.05" Maximum="1" Value="1" />
<Slider x:Name="DotOverlaySlider" Width="150" SmallChange="0.05" Maximum="1" Value="0.8" />

Categories

Resources