I am developing a Windows Store application with C# and XAML in which I have an image being displayed on user screen. On certain event I want to change its position on screen to the coordinates of my choice.
I have tried
Canvas.SetLeft(selectedImage, screenCoords.X);
Canvas.SetTop(selectedImage, screenCoords.Y);
and
selectedImage.SetValue(Canvas.LeftProperty, screenCoords.X);
selectedImage.SetValue(Canvas.TopProperty, screenCoords.Y);
But they are not working. I have also tried updating the layout after this. can anyone tell me what exactly am I doing wrong here?
Here is the XAML code:
<FlipView.ItemTemplate>
<DataTemplate>
<Grid x:Name="cv">
<Image x:Name="img1" Source = "{Binding ModelImage}" Stretch="Fill" Tag="{Binding ModelTag}" Tapped="ModelTapped"/>
<Image x:Name="hat" Source = "{Binding HatImage}" Width="{Binding HatWidth, Mode=TwoWay}" Height="{Binding HatHeight, Mode=TwoWay}" Stretch="Fill" ManipulationMode="All" ManipulationDelta="ResourceImage_ManipulationDelta" Tapped="imageTapped" Tag="{Binding hatTag}" Canvas.ZIndex="3">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
I have several images in the grid named 'cv', just removed them for simplicity. selectedImage in above C# code is one of the images in the grid 'cv'.
I solved the issue by translating my image to the desired points using RenderTransform property.
Related
I have a button with an image and no matter what I do the image looks blurry after rendered/compiled.
FYI - The image looks good when not in WPF controls
The image on the left is before compiled, the image on the right is blurry after compiled.
I tried applying UseLayoutRounding, applying SnapsToDevicePixels,
RenderOptions.BitmapScalingMode and removing the antialiasing directly in the button and directly to the image but nothing.
Any idea how can I improve the quality of the images in WPF?
XAML:
Styles applied directly to the button:
<Grid>
<Button x:Name="recentButton" UseLayoutRounding="True" RenderOptions.BitmapScalingMode="HighQuality" SnapsToDevicePixels="True" RenderOptions.EdgeMode="Aliased"
Margin="10,137,302,10"
Width="auto"
Height="23"
HorizontalAlignment="Stretch"
BorderBrush="{x:Null}"
Foreground="White"
BorderThickness="0"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Image Source="/Tool;component/Design/Images/more-icon-active.png" Stretch="None"/>
</Button>
</Grid>
Styles applied directly to the image:
<Grid>
<Button x:Name="recentButton"
Margin="10,137,302,10"
Width="auto"
Height="23"
HorizontalAlignment="Stretch"
BorderBrush="{x:Null}"
Foreground="White"
BorderThickness="0"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Image Source="/Tool;component/Design/Images/more-icon-active.png" UseLayoutRounding="True" RenderOptions.BitmapScalingMode="HighQuality" SnapsToDevicePixels="True" RenderOptions.EdgeMode="Aliased" Stretch="None"/>
</Button>
</Grid>
The problem is you're using UseLayoutRounding on the control directly.
But, be aware of this note in the linked documentation,
You should set UseLayoutRounding to true on the root element. The layout system adds child coordinates to the parent coordinates; therefore, if the parent coordinates are not on a pixel boundary, the child coordinates are also not on a pixel boundary. If UseLayoutRounding cannot be set at the root, set SnapsToDevicePixels on the child to obtain the effect that you want.
Therefore, use it on the parent container instead. In your case, that would be on the on the <grid> element.
Other recommandations
Recommended by #Clemens in the comment section,
Depending on the kind of image, RenderOptions.BitmapScalingMode="NearestNeighbor" may add some sharpness.
Note that you will have to apply that on the image directly.
Recommended by #BradleyUffner in the comment section,
Setting TextOptions.TextFormattingMode="Display" on your top level elements to greatly improve text rendering on desktop computers.
I have to zoom an image in uwp application, which works fine, but the design requires to have another image (that works as a button) in front of it and I dont want that element to be zoomed as well. It has to be only the image inside the canvas tag, this is how I have it now.
<ScrollViewer MinZoomFactor="1"
ZoomMode="Enabled"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<RelativePanel HorizontalAlignment = "Stretch" >
<Canvas x:Name="canvas">
<Image Source = "{Binding Test,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</Canvas >
<Button RelativePanel.AlignTopWithPanel="True"
Height="55"
Command="{Binding Path=CollapseSplitView}"
CommandParameter="{Binding ElementName=SplitV}">
<Button.Background>
<ImageBrush ImageSource = "/Assets/btlist.png" ></ ImageBrush >
</Button.Background >
</Button >
<Image RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
Source="/Assets/escala-x.png"
Width="130"
Height="70"
Margin="0,0,20,0"
ScrollViewer.IsZoomChainingEnabled="False"
ScrollViewer.IsZoomInertiaEnabled="False">
</Image>
</RelativePanel>
</ScrollViewer>
thats the xaml I have and which makes the zoom work for all elements inside of it. I tried to set scrollViewer.zoomMode=disabled for the elements that are not in the canvas but without luck. Any ideas? Thanks!
I finally fixed it by adding a scrollViewer inside the RelativePanel and then wrap the contents I wanted to zoom inside a StackPanel and then a Grid to be able to have multiple elements inside. Thanks all
So, I've got this mediaelement, which I want to appear in the middle of the screen, 20 pixels away from each edge, and when it's width gets to 600, it stops expanding and stays where it is. I've got the following XAML to get exactly what I want:
<Grid x:Name="video">
<MediaElement x:Name="player" AreTransportControlsEnabled="True" Margin="20,0" MaxWidth="600" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
The only problem is that the VerticalAlignment property seems to always be set to "Stretch". How can I fix this? I've tried using a viewbox, which works flawlessly, except I then get overly large or small TransportControls. I've also tried putting the mediaelement inside another grid with centered alignments, but I still get the same problem.
What you want is
20 pixels away from each edge.
But in your code you defined Margin="20,0", if you read the FrameworkElement.Margin property, you will find the useage <frameworkElement Margin="left+right,top+bottom"/>. With your code, this usage makes your MediaElement stretch in the vertical orientation.
If you use the Live Visual Tree to get a real-time view of your running XAML code, you will find, when you use the code Margin="20,0", the MediaElement is like this:
And if you use the code Margin="20", the MediaElement is like this:
The dashed red border in each picture stands for the MediaElement control.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot Margin="0,0,0,0" Background="LightGray">
<PivotItem Header="Formulas">
<Grid>
<GridView HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Background="#FF983636">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<x:String>One</x:String>
<x:String>Two</x:String>
<x:String>Three</x:String>
<x:String>Four</x:String>
</GridView>
</Grid>
</PivotItem>
</Pivot>
</Grid>
The key here is HorizontalAlignment="Stretch" on the GridView.
The HorizontalAlignment="Center" on the VariableSizedWrapGrid inside the ItemsPanelTemplate inside the Gridview; should do the trick which will always keep the content centered regardless of the width of the screen.
In the end, I found how to fix this, by keeping a constant aspect ratio of 16/9:
XAML:
<Grid SizeChanged="player_SizeChanged" Background="Black" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="1" MinHeight="1" Margin="30" MaxWidth="1000" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<MediaElement x:Name="player" Margin="0">
</Grid>
C#:
private void player_SizeChanged(object sender, SizeChangedEventArgs e)
{
(sender as Grid).Height = (e.NewSize.Width * 0.5625);
}
I am using ScaleTransform to change the size of a UserControl on a Canvas. It works perfectly until I use the ItemsControl Control.
The problem is that I need the scaling to be centered, the UserControl should not "move". As soon as it is inside the ItemsControl, the item Scales on Position x=0, y=0 instead of the center.
Would be great to know what I am doing wrong!
Here is some XAML showing it does not work (there is a single item in DataSource, nothing special it only displays a red rectangle on the window).
// This slider is used to scale the Grid inside the ItemsControl.
<Slider x:Name="pointResizeSlider" Margin="10,10,10,0" VerticalAlignment="Top" Maximum="7" Value="1"/>
// The items Control.
<ItemsControl Name="icTest" Background="Blue" Width="200" Height="200">
<ItemsControl.ItemTemplate>
<DataTemplate>
// For simplicity I am using a simple 100x100 Grid. This will get scaled.
<Grid Margin="0 0 5 5" Width="100" Height="100" Background="Red">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform
// This would make it pretty obvious, if it would work.
// Shows no effect.
CenterX="1000"
CenterY="1000"
ScaleX="{Binding Path=Value, ElementName=pointResizeSlider}"
ScaleY="{Binding Path=Value, ElementName=pointResizeSlider}" />
</TransformGroup>
</Grid.LayoutTransform>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Edit
Using RenderTransform works in this case, but I have to calculate the ActualSize of the UserControl (which does not work right now with RenderTransform). Why does LayoutTransform not work in this case?
I am making a messenger application in which I am using lync client for this purpose.
In my application UI I am getting the contacts (which is an object of LyncClient having properties like name, image , etc) in a listview and loading them in a data template which is defined as follow:
<DataTemplate x:Key="ContactsTemplate">
<Grid HorizontalAlignment="Left" Width="150" Height="150" Margin="10">
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{Binding Availability, Converter={StaticResource AvailabilityToPresenceColor}}" Opacity="0.75">
<TextBlock Text="{Binding Name}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="20" Margin="15,0,15,15"/>
</StackPanel>
</Grid>
</DataTemplate>
It has an image and textblock which show the image and name of the contact and as its shown below the background of stackpanel is binded to a converter which map the availibility status to a color so that for example the background of stackpanel will turn red when the contact availibility is busy.
now my question is how to have the same effect for the image?(making the image gray or red according to presence status)
I am new to binding so totaly lost in this bindig concept.
My idea was:
there is a effect evend handler for image so i thought of using that for this purpose and use
<Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title} effect="{Binding Availability, Converter={StaticResource AvailabilityToPresenceColor}}"/>
and inside the converter under some condition I want to use some code in which i need to get the image source, but as we are getting the image source through binding <Image Source="{Binding Image}" I am not able to get the image source in the converter.
please suggest me your ideas.
Don't use a converter. Use a pixel shader, such as this Grayscale effect: http://bursjootech.blogspot.no/2008/06/grayscale-effect-pixel-shader-effect-in.html