How To Change Grid Opacity using Slider Value In C# - c#

I want to change or control grid or something like image or any opacity using slider value.
I got full window control program but I failed to change grid opacity.
See this code for changing window opacity.
public partial class MainWindow : MetroWindow
{
public MainWindow()
{
InitializeComponent();
this.AllowsTransparency = true;
}
private void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
this.Opacity = slider.Value / 100;
}
}
And see result:
Its worked perfectly
But I want to change grid (image/rectangle or something) opacity via slider value.
I also tried by this code but not working:
private void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
mygrid.Opacity =slider.Value / 100;
}

Using binding is a better way and it works! Try to avoid code behind anywhere it's possible.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Background="Black" Opacity="{Binding Value, ElementName=mySlider}"/>
<Slider Name="mySlider" Grid.Row="1" Maximum="1" />
</Grid>

Related

MouseMove Event Registers False Inputs

I have an ellipse in the code below which has a mouse move event. Now everything is good unless I use mouse.capture on the element.
The mouse move event gets fired immediately I apply mouse.capture on the element even if I don't move my mouse, and also moving the position of the element by using setleft property also fires the mouse move event even if I don't move my mouse at all! Is this supposed to happen? And if there's a solution I badly need it..
The code below will generate the exact problem...
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Test
{
public partial class MainWindow : Window
{
public Ellipse elp;
public Point clickPoint;
public MainWindow()
{
InitializeComponent();
testcanv.Background = Brushes.Transparent;
}
private void down(object sender, MouseButtonEventArgs e)
{
clickPoint = e.GetPosition(testcanv);
if (e.ChangedButton == MouseButton.Left)
{
elp = new Ellipse
{
Stroke = Brushes.Blue,
StrokeThickness = 2,
Width = 200,
Height = 200,
Margin = new Thickness(-250)
};
Canvas.SetLeft(elp, clickPoint.X);
Canvas.SetTop(elp, clickPoint.Y);
elp.MouseMove += circle_move;
testcanv.Children.Add(elp);
}
}
private void circle_move(object sender, MouseEventArgs e)
{
text.Text += "Moved,";
}
private async void click(object sender, RoutedEventArgs e)
{
Mouse.Capture(elp, CaptureMode.Element);
await Task.Delay(1000);
Canvas.SetLeft(elp, 100);
Canvas.SetTop(elp, 100);
await Task.Delay(500);
Mouse.Capture(null);
}
}
}
And here is my XAML
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:balchal"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Canvas x:Name="testcanv" Grid.Column="0" Grid.Row="0" MouseDown="down"/>
<Button Grid.Column="1" Grid.Row="1" Content="Button" Click="click"/>
<TextBox x:Name="text" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Width="300" Margin="10"/>
</Grid>
</Window>
Thanks in advance... I really appreciate any kind of help...
I may be wrong, but I believe that the MouseMove event always fires when capturing
The simplest solution, if it's happening consistently, is probably just to store the state in the click event and check for it at the start of the move event: returning immediately and resetting the var.
bool CapturedFlag = false;
private void MoveEvent(object sender, MouseButtonEventArgs e)
{
if(CapturedFlag = true)
{
CapturedFlag = false;
return;
}
// other code
}
private async void CaptureEvent(object sender, RoutedEventArgs e)
{
CapturedFlag = true;
// other code
}

How to set width/height in code without breaking Grid star-size?

I have some XAML code like this:
<ScrollViewer VerticalScrollMode="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="g1" Grid.Row="0" Background="Pink"/>
<Grid x:Name="g2" Grid.Row="1" Background="Green"/>
</Grid>
</ScrollViewer>
<Button Content="Update Size" Width="150" Height="50" Click="Button_Click" Margin="105,342,0,248"/>
and code behind:
private void Button_Click(object sender, RoutedEventArgs e)
{
g1.Width = mainGrid.ActualWidth;
g1.Height = mainGrid.ActualHeight / 2;
}
it shows before clicking the button like this:
after clicking the button and drag the window to a bit larger, it looks like this:
so my question is, before clicking the button if you drag the window around the star-sizing works and resize both top/bottom grids as window resizes, however after clicking the buttom, which sets g1 width and height, it breaks star-sizing. how do i bring the star-sizing back to work again after set the width and height?
thanks in advance.
how do i bring the star-sizing back to work again after set the width and height?
After you set the width and height for Grid g1, you broke the auto star-sizing. But you can use the Window.SizeChanged event to monitor the size changing of the application window view instead. When window size changed, dynamically set new height and width for g1 by yourself to fit the parent control mainGrid.
Code like follows will meet you current requirements.
public Strangelaout()
{
this.InitializeComponent();
Window.Current.SizeChanged += Current_SizeChanged;
}
private void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
g1.Width = mainGrid.ActualWidth;
g1.Height = mainGrid.ActualHeight / 2;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
g1.Width = mainGrid.ActualWidth;
g1.Height = mainGrid.ActualHeight / 2;
}

E.Handled Not Work From TouchEventArgs in ShowDialog

I've got some trouble with stoping tunneling with Touch when a window was launched with ShowDialog().
My problem is : When I Touch the button in my Window, the clic(or touch ) continue to the MainWindow and open a new Window if antoher Button is behind.
I try to use
e.Handle = true;
To stop tunneling, it work if i clic with my mouse, but if i touch my screen it don't.
Here is a sample Of Code : ( This sample Window have just one button 'OK'. )
C#
public partial class MessageWindow : Window
{
.... other code ...
public static MessageBoxResult Show(string caption, MessageTypes type, MessageBoxButton buttons)
{
MessageWindow wnd = new MessageWindow();
wnd.Owner = Application.Current.MainWindow;
wnd.Title = "Error Message";
wnd.IsError = true;
wnd.Message = caption;
wnd.IsOk = true;
wnd.ShowDialog();
return wnd.Result;
}
private void OnOK()
{
Result = MessageBoxResult.OK;
this.DialogResult = true;
}
private void _btOK_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
OnOK();
}
private void _btOKonly_TouchDown(object sender, TouchEventArgs e)
{
e.Handled = true;
OnOK();
}
.... other code again ....
}
XAML
<Grid x:Name="LayoutRoot" Background="White" Width="640" Height="480">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Background="Black" Padding="20,10">
<TextBlock TextWrapping="Wrap" Text="{Binding Title, ElementName=Window}"/>
</Border>
<Button x:Name="_btOKonly" Content="OK" Click="_btOK_Click" TouchDown="_btOK_Click"Grid.Row="2"/>
<StackPanel>
< ... text of error ...>
</StackPanel>
</Grid>
Here is the code to launch my window :
C#
MessageWindow.Show(" This is a sample of error message", MessageWindow.MessageTypes.Error);
Thanks EveryOne Can Help Me :)
Finaly I found my Answer.
In fact i have to just captur "Clic" and not the "Touch" action like this
<Button x:Name="_btOKonly" Content="OK" Click="_btOK_Click" Grid.Row="2"/>
And The "Clic" is Handle like it does.

How to diplay/call an UserControl from another UserControl at click both situated in one MainWindow (C#/Xaml)

I'm pretty stuck right now, i'm gonna explain my problem and what i want.
In my solution i have a mainWindow, in that MainWindow i call the first userControl Who is situated in an userControlLibrary. I'ts a menu with button. I want when i click on the first button of the first userControl, i want put the visibility of the second usercontrol to visible (too situated in the userControlLibrary). But i try many things but no one works.
The first userControl is UC_MenuSlider and UC_Start_Study is the second who have to be visibile after click on the button on the first one. At launch UC_Start_Study is hidden.
This is a part of the code of my Mainwindow:
<Grid Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<UserControlLibrary:UC_StartStudy x:Name="UC_Start_Study" Grid.Column="1" Height="Auto" Width="Auto" Margin="70 0 0 0" Visibility="Hidden"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.1*" MaxWidth="240" MinWidth="240" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<UserControlLibrary:UC_MenuSlider x:Name="UC_MenuSlider" Grid.Column="0"/>
</Grid>
</Grid>
A part of the code of my first UserControl (UC_MenuSlider):
<Grid Name="Grid_Menu" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="Start_Study" Grid.Row="0" Grid.Column="0" Margin="0" Content="Start Study" FontSize="16" Click="Start_Study_Click">
</Button>
</Grid>
At first a basic event,just an event click in my first userControl. with code behind like that:
public void Start_Study_Click(object sender, RoutedEventArgs e)
{
var startStudy = new UserControlLibrary.UC_StartStudy();
startStudy.Visibility = Visibility.Visible;
}
Don't works. Then i use 'RoutedEvent' But I don't really understand who it works.
I hope my question was enough clear, thanks in advance for your anwsers
The problem is because you are creating a new UC_StartStrudy and set its Visibility to Visible. What you really need is to set Visibility of the one in your XAML: UC_Start_Study
public void Start_Study_Click(object sender, RoutedEventArgs e)
{
UC_Start_Study.Visibility = Visibility.Visible;
}
And you could also use XAML databinding the Visibility property of your UC_StartStrudy, and set its value in your code:
XAML:
<Window.Resourses>
<BooleanToVisibilityConverter x:Key="BooltoVisible" />
</Window.Resourse>
.....
<UserControlLibrary:UC_StartStudy x:Name="UC_Start_Study" Grid.Column="1" Height="Auto" Width="Auto" Margin="70 0 0 0" Visibility="{Binding IsUCStartStudyVisible, Converter={StaticResource BooltoVisible}}"/>
Code (remember to implement INotifyPropertyChanged ):
//implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChange(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//property for data binding
private bool _isucstartstudyvisible = false;
public bool IsUCStartStudyVisible
{
get{return _isucstartstudyvisible;}
set{_isucstartstudyvisible=value; RaisePropertyChange("IsUCStartStudyVisible");}
}
//your event to change the visibility
public void Start_Study_Click(object sender, RoutedEventArgs e)
{
IsUCStartStudyVisible=true;
}
I don't understand why you are taking a new instance of UC_StartStudy() as you have already added this in your MainWindow.
Can't you simply turn the visibility of UC_Start_Study as visible within the code.
Let me show you how you can do this.
try
public void Start_Study_Click(object sender, RoutedEventArgs e)
{
this.UC_Start_Study.Visibility = Visibility.Visible;
}

Setting control to be content of several controls

I have a control which i'm putting in dialog as a content. Due to relization of this dialog i have to create it every time when i need it(Show/Hide won't do the trick). I want my control to remember field content beetween calls. While i can apply viewmodel to achieve this i prefer just keep control as a field and assing it as content of dialog every time i need it. But i run into following error:
"Specified element is already the logical child of another element. Disconnect it first."
I tried to assing null to dialog window's content before closing it, but it doesn't solve the problem. Is there anything i can do?
Setting window.Content = null works fine for me. Following is the code I used:
public partial class MainWindow : Window
{
TextBlock textBlock = new TextBlock();
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
TestWindow testWindow = new TestWindow();
testWindow.Content = textBlock;
testWindow.Closing += HandleTestWindowClosing;
testWindow.Show();
}
void HandleTestWindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
var testWindow = sender as TestWindow;
if(testWindow!=null)
{
testWindow.Content = null;
testWindow.Closing -= HandleTestWindowClosing;
}
}
}
Check out the following working example. It isn't exactly your scenario, but pretty close. The key is setting the 'Child' property to null. It moves the TextBox from the top border to the bottom.
<Window x:Class="SO.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" Click="Move_Click">Move</Button>
<Border x:Name="topBorder" Grid.Row="1">
<TextBlock x:Name="ctrl">Some Text Block</TextBlock>
</Border>
<Border x:Name="bottomBorder" Grid.Row="2"/>
</Grid>
</Window>
and the code behind:
using System.Windows;
namespace SO
{
public partial class MainWindow :Window
{
public MainWindow( )
{
InitializeComponent( );
}
private void Move_Click( object sender, RoutedEventArgs e )
{
this.topBorder.Child = null;
this.bottomBorder.Child = this.ctrl;
}
}
}

Categories