The scroll viewer is not updating in silverlight - c#

I have an image inside scroll viewer and i have a control for zooming the image and in zooming event i change the scale of an image ,as below :
void zoomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
scale.ScaleX = e.NewValue;
scale.ScaleY = e.NewValue;
//scroll is a name of scrolviewer
scroll.UpdateLayout();
}
And a xaml below
<Grid x:Name="Preview" Grid.Column="1">
<Border x:Name="OuterBorder" BorderThickness="1" BorderBrush="#A3A3A3" >
<Border x:Name="InnerBorder" BorderBrush="Transparent" Margin="2" >
<Grid Background="White" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="scroll" HorizontalScrollBarVisibility="Auto" Grid.Column="0" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Themes:ThemeManager.StyleKey="TreeScrollViewer">
<Image Source="../charge_chargeline.PNG" >
<Image.RenderTransform>
<CompositeTransform x:Name="**scale**" />
</Image.RenderTransform>
</Image>
</ScrollViewer>
<Border HorizontalAlignment="Center" CornerRadius="0,0,2,2" Width="250" Height="24" VerticalAlignment="Top">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#CDD1D4" Offset="0.0"/>
<GradientStop Color="#C8CACD" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<ChargeEntry:Zoom x:Name="zoominout" />
</Border>
</Grid>
</Border>
</Border>
</Grid>

The problem here is that render transform take place much later in the rendering process. Later than the measure and arrange phases. The scroll viewer simply isn't aware of any apparent size change caused by the scaling transform, it still thinks the contained element is of the size specified by the Actual properties.
One solution might be to use the LayoutTransform object from the Silverlight Toolkit. This will apply a transform as part of its layout and hence its Actual properties will reflect the scaled size. With this inside a ScrollViewer the scroll bars should behave as expected.

Related

Crop content of rounded-corner border with image out of border

I need to move and rotate the image outside of the rounded border
example:
In How to make the contents of a round-cornered border be also round-cornered? find answer:
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Border1}" />
</Grid.OpacityMask>
<Border x:Name="Border1" CornerRadius="30" Background="Green" />
<TextBlock Text="asdas das d asd a sd a sda" />
</Grid>
This works if the elements do not go out of bounds.
If using rotate and/or margin like this:
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=_border1}" />
</Grid.OpacityMask>
<Border x:Name="_border1"
BorderThickness="0"
CornerRadius="30"
Background="Green" />
<TextBlock Text="SomeText"
Foreground="Yellow" />
<Image Source="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
Margin="-5 0 0 0"
Height="20"
Width="55"
Stretch="UniformToFill"
VerticalAlignment="Top"
HorizontalAlignment="Left"
RenderTransformOrigin="0.5 0.5">
<Image.RenderTransform>
<RotateTransform Angle="-7" />
</Image.RenderTransform>
</Image>
</Grid>
The rounding is displaced
How can I crop the image like in the first example? Thanks for your help.
Something is going wrong with the viewport calculation of the VisualBrush. Not sure if that is a bug in WPF.
A workaround could be setting the viewport in absolute units, with Rectangle instead of a Border:
<Grid.OpacityMask>
<VisualBrush
Visual="{Binding ElementName=rect}"
ViewportUnits="Absolute"
Viewport="{Binding ElementName=rect, Path=RenderedGeometry.Rect}"/>
</Grid.OpacityMask>
<Rectangle x:Name="rect" RadiusX="30" RadiusY="30" Fill="Green"/>
Or simpler, with setting the Clip property instead of OpacityMask, but still supporting resize:
<Grid Clip="{Binding ElementName=rect, Path=RenderedGeometry}">
<Rectangle RadiusX="30" RadiusY="30" Fill="Green" x:Name="rect"/>
...
</Grid>
I managed to achieve the desired result using Clip instead of OpacityMask. Then all the elements that need to be cropped must be children of the Border. If your Border needs to be dynamic, you need to bind the dimensions of the RectangleGeometry to the dimensions of the Border using Converter.
<Grid>
<Border BorderThickness="0"
CornerRadius="30"
Background="Green">
<Border.Clip>
<RectangleGeometry RadiusX="30" RadiusY="30" Rect="0,0,500,400"/>
</Border.Clip>
<Grid>
<TextBlock Text="SomeText"
Foreground="Yellow"/>
<Image Source="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
Margin="-5 0 0 0"
Height="20"
Width="55"
Stretch="UniformToFill"
VerticalAlignment="Top"
HorizontalAlignment="Left"
RenderTransformOrigin="0.5 0.5">
<Image.RenderTransform>
<RotateTransform Angle="-7"/>
</Image.RenderTransform>
</Image>
</Grid>
</Border>
</Grid>

Semitransparent background and opaque foreground wpf

I currently have the following xaml code:
<Grid
Name="rootGrid"
Opacity=".25"
Background="Black"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Border
Background="Black"
Margin="120">
<Grid
Background="White"
Margin="8">
<TextBlock
Name="popupContent">
Test
</TextBlock>
<Button
Click="Button_Click">
Test
</Button>
</Grid>
</Border>
</Grid>
Currently, the Opacity setting on the Grid is also applied on its children.
I only want this opacity to be applied on its background color, to achieve a darkening effect, not on the foreground. How can I do this?
Use a semi-transparent background, either as a SolidColorBrush like
<Grid ...>
<Grid.Background>
<SolidColorBrush Color="Black" Opacity="0.25"/>
</Grid.Background>
...
</Grid>
or by specifying an alpha value in the color, like
<Grid Background="#3F000000" ...>
The trick is to not add the Opacity to the entire Grid element:
<Grid>
<Grid.Background>
<SolidColorBrush Color="Black" Opacity=".75"/>
</Grid.Background>
<!--(Other elements)-->
</Grid>
This worked for me. I have two Grids a Root grid and RootContent sub-grid. I control the Opacity of the RootContent. Any controls in the "Root" will not be effected.
<Grid x:Name="Root" KeyDown="Root_KeyDown" Tapped="Root_Tapped">
<!--(Other elements)-->
<Grid x:Name="RootContent">
<!--(Other elements)-->
</Grid>
</Grid>
The opacity will always apply to children, so I tend to use a Canvas at the same level to achieve this affect:
<Grid>
<Canvas Opacity=".25"
Background="Black"/>
<Grid Name="rootGrid"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Border
Background="Black"
Margin="120">
<Grid
Background="White"
Margin="8">
<TextBlock
Name="popupContent">
Test
</TextBlock>
<Button
Click="Button_Click">
Test
</Button>
</Grid>
</Border>
</Grid>
</Grid>

Modify Bing Maps Anchor Point

I am working on a C#/XAML Universal Windows store app and I need to plot a custom control on a Bing map control. The problem is I cannot find any method to modify the anchor point which is by default Point(0,0) which anchor the control to upper left corner. I need something equivalent to MapControl.SetNormalizedAnchorPoint in Windows Phone. I believe it is possible since the Bing Maps app controls has an anchor point at the bottom left corner. How is it done?
Edit:
Here's what my custom control looks like. What I want is for it to anchor to the location at the bottom left corner (blue circle) instead of the default top left (red circle).
Here what it looks like on the map control where it achors to the red circle instead of blue.
And here's my code behind
public void AddPushpin(BasicGeoposition location, string title, string subtitle = "")
{
var pin = new PinControl(title, subtitle);
pin.ApplyTemplate();
pin.UpdateLayout();
MapLayer.SetPosition(pin, location.ToLocation());
_pinLayer.Children.Add(pin);
}
Here's the lengthy XAML
<UserControl x:Class="ToulouseUniversal.CustomControls.PinControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ToulouseUniversal.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100"
d:DesignWidth="200">
<Grid>
<Grid x:Name="LayoutRoot"
VerticalAlignment="Bottom">
<Polygon x:Name="labelPointer"
Points="0,0 0,0.5 15,15.5 15,0"
Margin="-15,0,0,0"
Grid.ColumnSpan="2"
Fill="{StaticResource TisseoBrush1}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom" />
<Polygon Points="0,0 0,0.5 15,15.5 15,0"
Margin="-15,0,0,0"
Grid.ColumnSpan="2"
Fill="Black"
Opacity="0.3"
HorizontalAlignment="Left"
VerticalAlignment="Bottom" />
<Grid Margin="-15,0,0,15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Height="4"
VerticalAlignment="Bottom"
Margin="14.5,-1,0.5,-3.5"
Grid.ColumnSpan="2">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black"
Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="labelGrid"
Fill="{StaticResource TisseoBrush1}"
RadiusX="0"
RadiusY="0"
Grid.ColumnSpan="2"/>
<Rectangle Fill="White"
Opacity="0.2"
Width="3"
HorizontalAlignment="Left" />
<Rectangle Fill="White"
Grid.ColumnSpan="2"
Opacity="0.2"
Width="3"
HorizontalAlignment="Right" />
<Grid>
<BitmapIcon UriSource="ms-appx:///Assets/Icons/appbar.transit.bus.png"
Width="40" />
</Grid>
<StackPanel Grid.Column="1">
<TextBlock x:Name="labelTitle"
Text="A stop"
Margin="6,3,9,0"
Foreground="White"
TextWrapping="Wrap"
MaxWidth="180"
FontSize="20"
FontWeight="SemiBold" />
<TextBlock x:Name="labelSubtitle"
Text="connecting"
Margin="6,0,9,6"
Foreground="White"
TextWrapping="Wrap"
FontSize="12"
MaxWidth="180"
FontWeight="Light" />
</StackPanel>
</Grid>
</Grid>
</Grid>
Depending on what you're trying to achieve, it might be interesting to share more of your XAML code or at least the part of the code were you're creating the pushpin object as well as the associated option.
Anyway, in order to control the anchor, it might be interesting to be able to use custom control as a pushpin so basically, if you're using a Grid as the root control representing the pushpin, you can work to display multiple things and also work with the margin on children controls to move them in the Grid.
If you look at the article here, you will see how it can be done:
http://blogs.msdn.com/b/bingdevcenter/archive/2014/06/24/using-maps-in-universal-apps.aspx
See the interesting part of the code is:
public void AddPushpin(BasicGeoposition location, string text)
{
#if WINDOWS_APP
var pin = new Pushpin()
{
Text = text
};
MapLayer.SetPosition(pin, location.ToLocation());
_pinLayer.Children.Add(pin);
#elif WINDOWS_PHONE_APP
var pin = new Grid()
{
Width = 24,
Height = 24,
Margin = new Windows.UI.Xaml.Thickness(-12)
};
pin.Children.Add(new Ellipse()
{
Fill = new SolidColorBrush(Colors.DodgerBlue),
Stroke = new SolidColorBrush(Colors.White),
StrokeThickness = 3,
Width = 24,
Height = 24
});
pin.Children.Add(new TextBlock()
{
Text = text,
FontSize = 12,
Foreground = new SolidColorBrush(Colors.White),
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
});
MapControl.SetLocation(pin, new Geopoint(location));
_map.Children.Add(pin);
#endif
}
Here is a nice blog post solving your problem to simulate the anchor-point in custom control for Bing Maps.
The most interesting part:
In the XAML Bing Maps controls the easiest way to offset a pushpin or custom
UIElement that is being overlaid on the map like a pushpin is to specify
a negative margin value on the pushpin or UIElement
In your case it would be sufficient to apply the negative margin on the LayoutRoot Grid.

How can i give the print preview in WPF, for a complete window?

How to give print preview functionality for a complete window before it gets printed here is the code i have implemented for printing the complete window.
My Code Behind :
private void Canvas_Print_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
PrintDialog printdlg = new PrintDialog();
MainWindow win = new MainWindow();
this.Width = 350;
this.Background = Brushes.White;
panel.ScrollToTop();
panel.ScrollToLeftEnd();
win.Tag = this;
if (printdlg.ShowDialog() == true)
{
printdlg.PrintVisual(panel.Content as Visual, "MyApplication");
}
}
Here is a sample for print preview kind of functionality
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Viewbox>
<Border BorderBrush="Gray"
Background="White"
BorderThickness="2"
Margin=".2in">
<Rectangle Width="8.5in"
Height="11in"
Margin=".2in">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=visualToPrint}"
Stretch="Uniform" />
</Rectangle.Fill>
</Rectangle>
<Border.Effect>
<DropShadowEffect Opacity=".25" />
</Border.Effect>
</Border>
</Viewbox>
<TextBox Text="change this text"
Grid.Row="1"
x:Name="visualToPrint" />
</Grid>
I created a rectangle of the size of a paper (assuming 8.5" 11") and set the fill to VisualBrush which is rendering my visual visualToPrint (panel in your case).
Also wrapped it into a border for page like effect and whole into a ViewBox to enable resizing
result
i chose a textbox for example you can choose any visual of your choice in the visual brush eg Visual="{Binding ElementName=panel}"

Canvas ImageSource not showing image

Here is my xaml:
<StackPanel Height="333">
<Canvas x:Name="imageCanvas"
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased">
<Canvas.Background>
<ImageBrush x:Name="image1"
Stretch="None"
AlignmentX="Left"
AlignmentY="Top">
</ImageBrush>
</Canvas.Background>
</Canvas>
<Canvas x:Name="overlayCanvas">
<Rectangle Name="dummyRectangle" Width="1" Height="2" Fill="Transparent" />
</Canvas>
</StackPanel>
Here is my C# code behind:
void PlayImages()
{
string testImageFolder = "C:\\TestImages";
DirectoryInfo d = new DirectoryInfo(testImageFolder);//Assuming Test is your Folder
FileInfo[] Files = d.GetFiles("*.tif"); //Getting Text files
image1.ImageSource = new BitmapImage(new Uri("C:\\TestImages\\ChanA_0001_0001_0001_0001.tif"));
}
However, when the C# code above executed, nothing happened on UI. I am wondering where should I change to make the image show up? Thanks.
It was the stack panel that causes the problem. I am not sure why, but if some of them are removed, then the image shows up. The xaml with some stack penal removed is like following:
<StackPanel HorizontalAlignment="Left">
<!--Controls:MenuControl/-->
<Controls:ToggleButtonControl Margin="0,0,0,0" Height="43" RenderTransformOrigin="0.5,-0.233" />
</StackPanel>
<Canvas x:Name="imageCanvas"
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased" Margin="0,52,0,0">
<Canvas.Background>
<ImageBrush x:Name="image1"
Stretch="None"
AlignmentX="Left"
AlignmentY="Top"
ImageSource="{Binding Path=Bitmap, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
</ImageBrush>
</Canvas.Background>
</Canvas>
Your imageCanvas always has width and height zero, because you neither add any children, not set its Width or Height explicitly.
Change your XAML to use only one Canvas instead, and optionally (depending on the outer container and the children to be added) set its Width and Height properties:
<Canvas x:Name="overlayCanvas" Height="333" Width="500">
<Canvas.Background>
<ImageBrush x:Name="image1" ... />
</Canvas.Background>
<Rectangle ... />
</Canvas>

Categories

Resources