Draw a centered line on Grid whose width is set automatically? - c#

I have seen several similar questions to this, but no solution works for me, probably because my Grid is set to Stretch . This is the result I am trying to achieve. Basically, I have one Grid and I'd like to draw an X-Axis line( like in the picture at the end of this question).
My XAML
<Grid x:Name="MainGrid" HorizontalAlignment="Stretch" Background="#FF4A70F1">
My CodeBehind
Line XAxis = new Line();
XAxis.Stroke = System.Windows.Media.Brushes.Black;
XAxis.StrokeThickness = 1;
XAxis.X1 = 0;
XAxis.X2 = MainGrid.RenderSize.Width;
XAxis.Y1 = MainGrid.RenderSize.Height / 2;
XAxis.Y2 = MainGrid.RenderSize.Height / 2;
MainGrid.Children.Add(XAxis);
My Problem
I 'd like this line to span the whole window, even if I resize/maximize the window. However, the calculations above for X2,Y1,Y2 don't work( all evaluate to 0, hence NO LINE shown) , whether I use ActualSizeor *RenderSize* . Can someone please point out how to fix that? Thank you

This XAML creates a vertically centered line that stretches horizontally:
<Grid>
<Line HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black"
X2="{Binding ActualWidth,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"/>
</Grid>

Related

How to override all Shapes in a specific area WPF

Currently I am filling my MainWindow with a slightly transparent black:
But I want it to have a "hole" where this effect doesn't take place which should look like the following:
So this needs to be done at runtime since the area which the hole represents is going to change multiple times while the program is running.
What I thought I could do
So at first I thought I could just cut the area in the middle out
like you could do with a Graphics object, but the slightly
transparent black is nothing but a rectangle which is added as a child on a canvas which is currently done like this:
var background = new System.Windows.Shapes.Rectangle
{
Fill = new SolidColorBrush(System.Windows.Media.Color.FromArgb(150, 0, 0, 0)),
Width = ScreenInfo.Width,
Height = ScreenInfo.Height
};
MainCanvas.Children.Add(background);
But I couldn't fine any way to achieve this cut effect.
Creating 4 Rectangles which would look something like this: but this way of doing it didn't seem to me as the most effecient way of achieving this.
Thanks for any kind of help!
Create a CombinedGeometry by cutting a smaller square out of a larger one and then use that with a path. How you size it will depend on your application, a Viewbox will probably be good enough for most cases:
<Grid>
<TextBlock Text="Hello World!" FontSize="200" Foreground="Red" TextWrapping="Wrap" TextAlignment="Center"/>
<Viewbox Stretch="UniformToFill">
<Path Fill="#C0000000">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,4,4" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry x:Name="cutRect" Rect="1,1,2,2" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Viewbox>
</Grid>
Then to change the size of the inner geometry you can either bind its Rect to a view model property or change it directly in code-behind:
cutRect.Rect = new Rect(1, 1, 1, 1);

C# WPF Images not displaying

In my code, I have 3 images that are empty and then I set the source in the code behind. The relative path I'm giving them is the right one but the images are not displaying anyway. I got no clue how to fix this.
Xaml
<Border BorderThickness="1" Margin="44,135,433,248" BorderBrush="#FF000000">
<Image x:Name="imageHelmet" HorizontalAlignment="Left" Height="116" Margin="-1" VerticalAlignment="Top" Width="127" MouseEnter="helmet_MouseEnter"/>
</Border>
Behind
string source = #"..\..\..\Images\" + piece.Link;
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(source, UriKind.Relative);
bmp.EndInit();
imageChestplate.Source = bmp;
This is just one of them, but the rest are the same.
The image is likely hidden due to the margin of the border, at least that's what I saw when I attempted to recreate your problem.
Here, the Margin Property of the Border is set to 44,135,433,248. This means that there is a margin of 433 on the right side, and 248 on the bottom.
<Border BorderThickness="1" Margin="44,135,433,248" BorderBrush="#FF000000">
The edge of the window counts as something getting within the margin, so if the window is too small, it will not leave enough space for the margin, and as such the margin will be pushed over the image, hiding it.
To remedy this situation, change the right and bottom values in the margin to 0, and set the Border's HorizontalAlignment to Left, and VerticalAlignment to Top.
<Border BorderThickness="1" Margin="44,135,0,0" BorderBrush="#FF000000" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image x:Name="imageHelmet" HorizontalAlignment="Left" Height="116" Margin="-1" VerticalAlignment="Top" Width="127" MouseEnter="helmet_MouseEnter"/>
</Border>
This way, there's no margin on the right and bottom sides to get pushed over the image, and the alignment makes it so the left and top alignments are used correctly.

Changing size of the frame and elements in UWP

I want to know if there is a way to resize the frame and the elements inside of it when the window size change. I always want to have the same proportion in the size of the elements inside the frame.
Example:
1- Windowsize = 100(in x) and Imagesize = 50(in x) locationx = 25
2- Windowsize = 50(in x) and Imagesize = 25(in x) location x = 12.5(~12)
In this case, the windowsize is "something", imagesize is 1/2 of "something" and locationx of the image is 1/4 of something. I wan't to do something like this but with every element inside the frame.
Thanks!
You can use the <ViewBox/> control which does exactly that.
<Page>...
<Grid>
<ViewBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel>
<Button Content="test" HorizontalAlignment="Left"/>
<TextBlock Text="some text"/>
</StackPanel>
</ViewBox>
</Grid>
</Page>
In the example below, the ViewBox is placed inside a Grid and stretched both Horizontally and Vertically which causes it to stretch with the Page resize.
Reference docs here.

Scrolling problems when using ScaleTransform in Panorama/Pivot/RadSlideView item

I'm trying to implement zoom-functionality in a RadSlideView ItemTemplate. I'm doing this by using a ViewportControl with a Canvas and then applying a RenderTransform (ScaleTransform) to a StackPanel in the Canvas. Similar to the SDK-sample found here.
The problem I have is that the ScaleTransform seems to be affecting the swipe-gesture used to change item in the SlideView/Panorama/Pivot control. E.g. if the ScaleTransform is set to 0.1 it seems like I only need to swipe 1/10th of the length to change item compared to using a ScaleTransform of 1.0.
I found that if I set IsHitTestVisible to false on the ItemTemplate the swiping works like I want. But this is not a solution since I sometimes need to be able to pan the content vertically while still being able to change item by swiping horizontally.
So my question is how can I solve this?
For reference the XAML looks like this:
<Controls:RadSlideView Name="SlideView" ItemsSource="{Binding Pages}" IsLoopingEnabled="False" SelectionChanged="RadSlideView_SelectionChanged" CacheMode="BitmapCache" ManipulationStarted="SlideView_ManipulationStarted" ManipulationCompleted="SlideView_ManipulationCompleted" ManipulationDelta="SlideView_ManipulationDelta">
<Controls:RadSlideView.ItemTemplate>
<DataTemplate>
<ViewportControl x:Name="SlideViewViewport" ViewportChanged="SlideViewViewport_ViewportChanged" Loaded="SlideViewViewport_Loaded">
<Canvas>
<StackPanel>
<Image Source="{Binding Image}" Stretch="Fill" Width="{Binding ElementName=SlideView, Path=DataContext.PageWidth}" Height="{Binding ElementName=SlideView, Path=DataContext.PageHeight}" CacheMode="BitmapCache"/>
<StackPanel.RenderTransform>
<ScaleTransform x:Name="xform"/>
</StackPanel.RenderTransform>
</StackPanel>
</Canvas>
</ViewportControl>
</DataTemplate>
</Controls:RadSlideView.ItemTemplate>
I have also looked at Teleriks RadPanAndZoom-control to avoid implementing my own zoom-functionality, but since I sometimes need to place two pictures side by side and zoom them as if they were one I don't think I can use it.
The problem is that ScaleTransformation scales your picture, but doesn't change it's height and width. Only if Height And Width are overflowing scrollviewer you can scroll the content

How do I get a ScrollViewer with a Rectangle inside to stop scrolling when it reaches the end of the rectangle?

I have created a Rectangle inside of a ScrollViewer like this
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Center" Width="728" Canvas.Top="20" d:LayoutOverrides="HorizontalMargin" >
<Rectangle x:Name="musicBG" Fill="#FF0692FD"/>
</ScrollViewer>
During the use of the app, the size of MusicBg changes, sometimes to something around 3,000 pixels width.
musicBG.Width = _songLength*PixelsPerSecond
However, while scrolling the scrollViewer, it allows me to scroll the rectangle all the way off the screen.
For example this line of code gives me the following values when I have moved the rectangle as far as I want to move it.
if (songScrollViewer.HorizontalOffset > songScrollViewer.ScrollableWidth)
HorizontalOffset has a value of ~1200 and ScrollableWidth has a value of about ~2900.
How can I get this to be done properly so that the rectangle is not scrolled completely off the screen?
I would expect a HorizontalOffset of about 1200 to only push the rectangle about halfway through to it's destination, and not make it start going off screen.
ANSWER:
After much frustration, I was able to solve this problem by using Canvas instead of Border or Rectangle.
I'll award points if anyone can explain why this problem happened, and if there is a less processor intensive control that would work better than canvas.
Edit: Screen shots:
Bad Code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Border x:Name="musicBG" Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</ScrollViewer>
Image of bad scroll with bad code:
Good working code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Canvas x:Name="musicBG" Background ="#FF0692FD" Height="270" >
<Border Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</Canvas>
</ScrollViewer>
Good Scroll: Notice it says 170 seconds on the bottom right instead of the smaller number of 118 seconds in the bad scroll.
I believe your right, wp7 won't render shapes that are bigger then 2048 pixels. So the reason it's scrolling of the page is because it's treating it as if it were bigger then 2048 but you can only see up to a width of 2048px and its just scrolling over to the "ghost" part of the rectangle.
I'm not sure if you can override this but the best solution I could come up with (without overriding) is by splitting up your rectangle into chucks that are smaller then 2000 (just to be safe) and then displaying them seamlessly in a horizontal stack panel inside the scroll viewer. The problem with this is that depending on how you've coded it, this solution might be hard to implement; but you might just be able to split it in your ViewModel when displaying it and your logic would only see it as one big chunk.

Categories

Resources