I have a wpf Application where's two grid inside one single grid like this
<window ....>
<grid x:name="main_grid">
<grid x:name="panel1">
//...some stuff//
</grid>
<grid x:name="panel2">
//...some stuff//
</grid>
</grid>
</window>
the main_grid is positioned to fit the whole window
I want to position Panel1 and Panel2 margin left and top to 0 from code behind.
what I tried is like this,
private void window_Loaded(object sender, RoutedEventArgs e)
{
int left = Convert.ToInt16(main_grid.Margin.Left);
int top = Convert.ToInt16(main_grid.Margin.Top);
panel1.margin = new Thickness(left, top, 0, 0);
panel2.margin = new Thickness(left, top, 0, 0);
}
However, it's not working. figures...
Anybody have any solutions? please...
Why not in XAML like this:
<Grid x:name="main_grid"
Margin="10,20,30,40">
<Grid x:name="panel1"
Margin="10,20,30,40">
</Grid>
<Grid x:name="panel2"
Margin="10,20,30,40">
</Grid>
</Grid>
Related
I am a bit new to WPF. I wanted to make my image scrollable when I scale up the image. This is my XAML code.
<UserControl xmlns: skia="clr-namespace:SkiaSharp.Views.WPF:assembly=SkiaSharp.Views.WPF">
<Grid>
<skia:SKElement Name="Canvas" PaintSurface="SKElement_PaintSurface">
</Grid>
</UserControl>
private void SKElement_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
\\Code goes here...
}
Inside the SKElement_PaintSurface method, I created a way to draw the bitmap image on the canvas. But when I scale up the image I can't scroll the image. Does anyone know to create a scrollbar for this?
Put the Canvas in a ScrollViewer element and set its Height and/or Width when you scale it:
<UserControl xmlns: skia="clr-namespace:SkiaSharp.Views.WPF:assembly=SkiaSharp.Views.WPF">
<Grid>
<ScrollViewer>
<skia:SKElement Name="DrawCanvas" PaintSurface="SKElement_PaintSurface">
</ScrollViewer>
</Grid>
</UserControl>
private void SKElement_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
\\Code goes here...
DrawCanvas.Height = 100;
}
Is there a way in WPF to access the ScaleTransform Parameter of a Canvas Panel (which is created in the xaml File) in the Code Behind File?
Use Case Example:
I want to position a list of items inside a scaled Canvas like so:
<ItemsControl MouseMove="Control_MouseMove">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform>
<ScaleTransform.ScaleX />
</ScaleTransform>
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I also want to display the current position of my items inside the Canvas at Mouse over with a Pop-up. I am currently trying it this way:
public void Control_MouseMove(object sender, MouseEventArgs e) {
if (!this.Popup.IsOpen)
this.Popup.IsOpen = true;
var mousePosition = e.GetPosition(this.SwLane);
this.Popup.HorizontalOffset = mousePosition.X + 10;
this.Popup.VerticalOffset = mousePosition.Y - 20;
this.PopupContent.Text = System.Convert.ToString(mousePosition.X);
}
What I get is the canvas X coordinate inside the Popup (which makes sense to me). However, I would like to display the scale transformed "coordinates" of the canvas.
Is there a way to access the ScaleTransform Parameter in Code Behind so that I can visualise my transformed item position? Or should I do it in a different way? Thanks.
You could set an OnInitialized Handler where you build your transform in code-behind, save its constituent ScaleTransform as a private property and then assign it there as well after your window has initialized
Something crudely like this:
<Window x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="White"
MouseLeftButtonDown="MainWindow_OnMouseLeftButtonDown"
Initialized="MainWindow_OnInitialized"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ItemsControl x:Name="MyItems" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Rectangle Width="100" Height="200" Stroke="Red" StrokeThickness="5"/>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private TransformGroup MyTransform { get; set; }
private ScaleTransform SceneScale { get; set; }
private void MainWindow_OnInitialized(object? sender, EventArgs e)
{
MyTransform = new TransformGroup();
SceneScale = new ScaleTransform(1.0, 1.0, 0, 0);
MyTransform.Children.Add(SceneScale);
MyItems.RenderTransform = MyTransform;
}
}
Now you could add a MouseLeftButtonDown Handler to scale things, for example:
private void MainWindow_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
SceneScale.ScaleX *= 1.1;
SceneScale.ScaleY *= 1.1;
}
For the coordinate thing, expose the current coordinates as properties. Update them when the mouse moves. Bind the UI to them
This might work better if you packaged it all in a control
I am using scroll viewer to zoom the image which is set as background for Grid.When, I am setting the zoom factor value on button click from code behind with scrollViewer.ZoomToFactor(zoomFactor) image is getting zoomed from Top left corner ,not from the center position.
Please get the sample from the below link or below code snippet for your reference.
Link: https://github.com/ragulsv/ScrollViewer
Code Snippet[C#]:
float count = 1;
private void Clr_Click(object sender, RoutedEventArgs e)
{
count = 1;
viewer.ZoomToFactor(count);
viewer.RenderTransformOrigin = new Point(0.5, 0.5);
}
private void Btn_Click(object sender, RoutedEventArgs e)
{
viewer.ZoomToFactor(count);
viewer.RenderTransformOrigin = new Point(0.5, 0.5);
count += 1;
}
Code Snippet[Xaml]:
<Grid x:Name="grid1">
<Grid.RowDefinitions>
<RowDefinition Height="0.1*">
</RowDefinition>
<RowDefinition Height="0.1*">
</RowDefinition>
<RowDefinition Height="0.8*">
</RowDefinition>
</Grid.RowDefinitions>
<Button x:Name="btn" Grid.Row="0"></Button>
<Button x:Name="clr" Grid.Row="1"></Button>
<ScrollViewer x:Name="viewer" Grid.Row="2" ZoomMode="Enabled">
<Grid>
<Image Source="Assets\EditedImage.jpg" Height="190" Width="190"/>
</Grid>
</ScrollViewer>
</Grid>
How to zoom at center in scroll viewer while using ZoomToFactor to increase zoom level in button click
For this scenario, you could set Image's parent Grid VerticalAlignment="Center" HorizontalAlignment="Center" that could make the image always fix on the center of ScrollViewer and then call ChangeView method to edit ZoomFactor.
private void Btn_Click(object sender, RoutedEventArgs e)
{
viewer.ChangeView(0, 0, (viewer.ZoomFactor + 1f));
}
I want to make the window have the effect can change the whole window which has many elements evenly to white, as the window behind in the picture:
I use code like
public MainWindow()
{
this.Opacity = 0.5;
}
but it change to black
How to make it whole evenly change to white even when there're many Element in the Window and don't set the window Style to none?(Because set Window AllowTransparent seems have to set the Style to none at the same time)
I hope can using code to do it, because I want to do it dynamically.
(Or possibly it use UserControl but not Window to achieve this effect? maybe the UserControl use with the Window and set the UserControl to Transparent can do it
----After I try, I find UserControl doesn't have property AllowTransparent, so it seems imposible use this way )
Basically, you have two options:
Use white Background color on Window and change Opacity on the window children, so the white starts to shine through
<Window Background="White">
<Grid Opacity="{Binding WhiteOutVisibility}" Background="WhiteSmoke">
<YourContent/>
</Grid>
</Window>
Use a white overlay control with alpha or Opacity that lets the actual content shine through
<Grid>
<YourContent/>
<Border Background="#80ffffff" Visibility="{Binding WhiteOutVisibility}"/>
</Grid>
In my opinion, you should use a white overlay if you want to block user interaction with the window content and white background if you want to continue user interaction.
If you need to fade only the client area, you can just put overlay - some empty semitransparent control over all the content on the window.
You can achieve this effect by laying a canvas over your window, and setting the background to white and an opacity value. Some xaml like this will work. Just change the UserControl for Window.
<UserControl x:Class="View.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="40" d:DesignWidth="100">
<Grid>
<TextBox Text="Hello there" />
<!-- this will show faintly -->
<Canvas Background="White" Opacity="0.8"></Canvas>
</Grid>
</UserControl>
This xaml looks like this:
The Window type has property AllowsTransparency. You can find it property on your window properties in MSVisualStudio. This can solve your problem.
Thanks for Phillip Ngan and grek40 s' answer,
both Grid and Canvas with background white and opacity works,
I write some test code that can show the effect
Xaml Part
<Window x:Class="WPFAbitraryTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Background="Blue" Foreground="White" FontSize="20" Click="SwitchOpacity_OnClick">Clcik to SwitchOpacity</Button>
<Button Grid.Row="1" Background="ForestGreen">hi2</Button>
<ListBox Grid.Row="2" Background="Orange">
<ListBoxItem>ListBox Item #1</ListBoxItem>
<ListBoxItem>ListBox Item #2</ListBoxItem>
<ListBoxItem>ListBox Item #3</ListBoxItem>
</ListBox>
<!-- <Grid Grid.Row="1" Grid.RowSpan="2" Opacity="0.9" Background="WhiteSmoke"/> -->
<Canvas Name="WhiteMaskCanvas" Grid.Row="1" Grid.RowSpan="2" Background="White" Opacity="0.5"></Canvas>
</Grid>
</Window>
.
Class Part
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void SwitchOpacity_OnClick(object sender, RoutedEventArgs e)
{
int opacityVal = 0;
Task.Factory.StartNew(() =>
{
for (int i = 0; i <= 1000; i++)
{
int j = 0;
Thread.Sleep(100);
//Use ++ % to change Opacity
this.Dispatcher.Invoke(
DispatcherPriority.SystemIdle,
new Action(() =>
{
WhiteMaskCanvas.Opacity = ++opacityVal % 10 / 10.0;
}));
////Use Abs Cosine to Change Opacity
//this.Dispatcher.Invoke(
// DispatcherPriority.SystemIdle,
// new Action(() =>
// {
// WhiteMaskCanvas.Opacity =
// Math.Abs(Math.Sin(++opacityVal*0.1)) ;
// }));
}
});
}
}
.
The Result:
.
further code,
if want to make the canvas mask whole window, you can change the canvas to
<Canvas Name="WhiteMaskCanvas" Grid.Row="0" Grid.RowSpan="3" Background="White" Opacity="0.5"></Canvas>
and add code to class:
public MainWindow()
{
InitializeComponent();
WhiteMaskCanvas.Visibility = Visibility.Collapsed;
}
private void SwitchOpacity_OnClick(object sender, RoutedEventArgs e)
{
WhiteMaskCanvas.Visibility = Visibility.Visible;
int opacityVal = 0;
Task.Factory.StartNew(() =>
{
//below same as code above
I have the following XAML:
<Window x:Class="thumb_test.MainWindow" Title="MainWindow" ... >
<Grid>
<Canvas>
<Thumb Canvas.Top="25" Canvas.Left="25" Width="50" Height="50"
Name="_thumb1" DragStarted="ThumbStart" DragDelta="ThumbMoved" >
</Thumb>
</Canvas>
</Grid>
</Window>
And the following is the corresponding code-behind:
void ThumbStart(object sender, DragStartedEventArgs e)
{
_originalLeft = Canvas.GetLeft(_thumb1);
_originalTop = Canvas.GetTop(_thumb1);
}
void ThumbMoved(object sender, DragDeltaEventArgs e)
{
double left = _originalLeft + e.HorizontalChange;
double top = _originalTop + e.VerticalChange;
Canvas.SetLeft(_thumb1, left);
Canvas.SetTop(_thumb1, top);
_originalLeft = left;
_originalTop = top;
}
The above displays a rectangle, which can be dragged around on the canvas.
My question: How can I associate this Thumb with a TextBlock, such that the Thumb overlays the TextBlock (with the Thumb being transparent) and I can drag the TextBlock around? (PS: Believe me, what I have tried so far is not worth showing here.)
My ultimate goal is to be able to drag TextBlocks around, so I am open to other approaches. I would like to operate on a Canvas, though.
I am using VS2010 on Win 7, with .NET 4.0.
have you read Dragging Elements in a Canvas ?
or this easy way(that i never saw until now -google) How to make any UI element drag-able using Behaviors in WPF