I have few images in WPF. On mouse click event, I want to add a border to the image. Please tell me how to do it.
Should I have to create a style element in the xaml and apply it in the code-behind?
There are a lot of ways. I recommend something like this, using xaml.
<Border BorderThickness="2">
<Border.BorderBrush>
<SolidColorBrush Color="LightGray" Opacity="{Binding Path=IsSelected, Converter={StaticResource BooleanToDouble}}"/>
</Border.BorderBrush>
<Image Source="{Binding Path=ImageUri}"/>
</Border>
DataContext of this block must have IsSelected property or something like this. Also you have to implement a IValueConverter to convert true to 1 and false to 0.
Just remove the image from its container, create the border, add the image as the border's child, and add the border back to the container where the image was. If you get stuck, post code and I'll help you adapt it, but it shouldn't be difficult at all. You can do it all in the code-behind.
Related
I am creating an application with a UserControl containing multiple UI Elements. The UserControl is rendered into a StackPanel using ItemsControl since the number of UserControls to be rendered depends on user's input.
The basic XAML in the UserControl is as follows.
<Grid x:Name="Viewport" VerticalAlignment="Top" HorizontalAlignment="Center">
<Border x:Name="ViewportBorder" Background="White" BorderThickness="2, 2, 2, 2" BorderBrush="#FF353334" />
<Image x:Name="Image" Margin="0" UseLayoutRounding="True" ManipulationMode="Scale"/>
<InkCanvas x:Name="InkCanvas" />
<Canvas x:Name="SelectionCanvas" CompositeMode="SourceOver" />
</Grid>
I want to change the cursor icon when user is hovering over the SelectionCanvas (based on a condition check in my case as you might see in the source). It seemed pretty straight forward so I tried to use PointerEntered & PointerExited events to capture & release the pointer from the SelectionCanvas. And PointerMoved to change the cursor icon. But it seems that none of the events were triggering.
I tried binding to the Viewport grid element as well but no luck in that too.
I'm not sure what I missed here. Could someone please help me on this? Any help is much appreciated. Please find the complete source code here.
Please note that a sample PDF is included into the startup project /Resources which you'll have to open from the app.
The PointerEntered and PointerExited events are raised provided that the area that is supposed to raise them is painted so try to set the Background property of the Canvas to some brush like for example Transparent:
<Canvas x:Name="SelectionCanvas" CompositeMode="SourceOver"
Background="Transparent"
PointerEntered="SelectionCanvas_PointerEntered"
...
Brief
I am trying to programmatically change the colour of specific elements at runtime. The project currently uses Telerik and I am able to change the theme at runtime: This works as expected with no issues. I can't, however, figure out how to change the fill or stroke colour at runtime of custom shape elements in XAML.
Within my project I have a ResourceDictionary file named _Icons.xaml that contains vector shapes to use as the content for other controls (such as buttons).
Code
App.xaml.cs
I am using the following code to change the theme's marker colours at runtime.
GreenPalette.Palette.MarkerColor = (Color)ColorConverter.ConvertFromString("#FF000000");
_Icons.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyNamespace">
<ControlTemplate x:Key="Box">
<Viewbox>
<Rectangle Width="357" Height="357" Fill="#000000"/>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="BoxOutline">
<Viewbox>
<Rectangle Width="357" Height="357" StrokeThickness="45" Stroke="#000000"/>
</Viewbox>
</ControlTemplate>
</ResourceDictionary>
MainWindow.xaml
<telerik:RadButton>
<StackPanel>
<ContentControl Template="{StaticResource Box}" Height="58"/>
<TextBlock HorizontalAlignment="Center" Margin="0,5,0,0">Box</TextBlock>
</StackPanel>
</telerik:RadButton>
<telerik:RadButton>
<StackPanel>
<ContentControl Template="{StaticResource BoxOutline}" Height="58"/>
<TextBlock HorizontalAlignment="Center" Margin="0,5,0,0">BoxOutline</TextBlock>
</StackPanel>
</telerik:RadButton>
Question
In _Icons.xaml I have the following lines:
<Rectangle Width="357" Height="357" Fill="#000000"/>
<Rectangle Width="357" Height="357" StrokeThickness="45" Stroke="#000000"/>
Given the following line in App.xaml.cs:
GreenPalette.Palette.MarkerColor = (Color)ColorConverter.ConvertFromString("#FF000000");
How can I either...
Programmatically change the values of Fill and/or Stroke (an element that only has Fill set should only change the Fill value and not add a Stroke attribute) from the App.xaml.cs file? Or ...
Bind the values in XAML for Fill or Stroke to receive the value given by my App.xaml.cs file?
Thank you for taking the time to read my question. Any help regarding this is greatly appreciated.
First i advise you to eject that controls off your resource sheet so you can actually control them properly.
When you do that, go the code behind your control and just use dependency property of type 'Color' of the 'SolidColorBrush' that is used by the background and then bind it by element name, you gotta build the project at least once before attempting to bind.
Here is how you write a dependency property
hint: in VS write 'propdp' and hit tab twice to bring up a template, but you can use mine for now.
public Color _color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("_color", typeof(Color), typeof(Fileentity), null);
after you build once go to the xalm and put this inside your rectangle:
<Grid.Background>
<SolidColorBrush Color="{Binding
_color,ElementName=YourControlName" />
</Grid.Background>
if you do it right you will be able to access this property when inserting the control on you Page like
<local:YourcontrolName _color="{x:Bind MyColorProperty }"/>
where 'MyColorProperty' is a property that implements INotifyPropertyChanged.
An alternative way is to use a datacontext directly on the usercontrol and just bind your color to one of its properties like:
public YourControl(){
this.InitializeComponent();
this.DataContext = new MyClassDataContext();
var myContext= (MyClassDataContext)this.DataContext;
_color=MyContext.MyColorProperty;}
Where MyClassDataContext is any given class that contains a Color property(MyColorProperty) of your choosing.
You need a Dependency property here as well that binds to your Controls xalm like i showed before.
I know all this is might too hard to grasp at once, thats cause it requires basic knowledge of MvvM.
I have a page where I am adding a custom control like this:
<custom:ClickableIcon x:Name="DeleteTask" Grid.Column="2" Foreground="Red" Icon="Delete" Click="DeleteTask_Click" />
In my custom control, I have the following XAML:
<UserControl x:Name="clickableIconUserControl"
x:Class="Client.UWP.Controls.ClickableIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Client.UWP.Controls" IsEnabledChanged="userControl_IsEnabledChanged">
<Grid x:Name="ohmygrid">
<SymbolIcon x:Name="CIIcon"
Foreground="{Binding Foreground, ElementName=clickableIconUserControl}"
Symbol="{Binding Icon, ElementName=clickableIconUserControl}"
Tapped="CIIcon_Tapped"/>
</Grid>
</UserControl>
This doesn't actually work. What I want is to copy the Foreground property for the control into specific places in the user control. I'd like to do this within a style sheet, direct property or whatever. In addition, I'd like to update the foreground when the foreground of the control on the page is changed.
Unfortunately, in this code (which is much simplified than the code I am actually trying to write), the Foreground is always #FF000000 in the debugger and I cannot seem to get a hold of the setting on the actual control to set it - either in code behind or as a binding.
How can I achieve this?
I have a custom DataGrid mixed with DataGridTemplateColumns and a custom behavior derived from this answer Silverlight Datagrid: Highlight an entire column when that column is sorted. The problem I'm experiencing is that any DataGridTemplateColumn's cells are not picking up the 'highlight'. The cell template being used for the custom columns are of the structure shown below. Anyone have any ideas why the background highlight isn't being applied? I've been wracking my brain on this one for a while.
<DataTemplate>
<Grid>
<Border VerticalAlignment='Stretch' Margin='1' Background='Transparent'>
<TextBlock VerticalAlignment='Center' Text='{Binding Path=Variable}' />
</Border>
</Grid>
</DataTemplate>
To solve this problem I ended up needing to create a string DependencyProperty called Background on the custom column class that inherits from DataGridTemplateColumn. Also, in the behavior, I had to check what type the column was.
Before, I would just case the column in the CollectionChanged event handler to a DataGridBoundColumn. Now I check to see if it is actually that type or if its a DataGridTemplateColumn. The DataGridTemplateColumn has a different way to check the binding path, the difference is shown below
DataGridBoundColumn: boundColumn.Binding.Path.Path
DataGridTemplateColumn: boundColumn.SortMemberPath
The final tweak I had to make was to change the structure of the DataTemplate so that it now looks like below, basically setting the color a different way is all.
<DataTemplate>
<Grid>
<Border>
<Border.Background>
<SolidColorBrush Color='{0}' />
</Border.Background>
<TextBlock VerticalAlignment='Center' Text='{Binding Path=Variable}' />
</Border>
</Grid>
</DataTemplate>
Let's say I've created a UserControl with the following ContentTemplate defined in XAML:
<UserControl.ContentTemplate>
<DataTemplate>
<Ellipse Name="myEllipse" Stroke="White"/>
<ContentPresenter Content="{TemplateBinding Content}"/>
</DataTemplate>
</UserControl.ContentTemplate>
How would I access the "myEllipse" element within my code so that, for example, I could find its height with "myEllipse.Height"? I cannot access it by name directly. I attempted to create a reference to it with:
Ellipse ellipse = ContentTemplate.FindName("myEllipse",this) as Ellipse;
It crashes when I run the program, saying it can't create an instance of my class. Perhaps I'm not using FindName correctly. If anyone can help me out it would be much appreciated.
Thanks,
Dalal
In order to use FindName on a DataTemplate, you will need a reference to the ContentPresenter. See Josh Smith's article How to use FindName with a ContentControl.
What you may actually want to do is to use a ControlTemplate rather than a DataTemplate. This should be easier to use and will let users of your control apply their own content templates or use implicit templates. If you do something like this:
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid>
<ContentPresenter/>
<Ellipse Name="myEllipse" Stroke="White"/>
</Grid>
</ControlTemplate>
</UserControl.Template>
Then in code (perhaps in an OnApplyTemplate override) you will be able to do this:
var ellipse = Template.FindName("myEllipse", this) as Ellipse;
You should also decorate your class with a TemplatePartAttribute like this:
[TemplatePart(Name="myEllipse", Type = typeof(Ellipse))]
So that if anyone re-templates your control they know to provide an Ellipse element with that name. (This is less important if the class is only used internally.)
Finally, if all you want to do is change the color of the Ellipse, then you may just want to use data binding. You could create an EllipseColor dependency property on your control and just set Stroke="{TemplateBinding EllipseColor}".
Try
<Ellipse Name="myEllipse" Stroke="{TemplateBinding Background}"/>
instead of programmatically changing it.
There's a similar example here, with a blue filled ellipse.
http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter.aspx