.NET 6 WPF Can't change opacity in code behhind? [duplicate] - c#

This question already has answers here:
What is DataContext for?
(4 answers)
Closed 5 months ago.
I've been trying to change the opacity of my window through code for a while now but I've had no success. I'm changing the Window.Opacity number in my function but I've had no results. As of now, I've tried setting the background to a SolidBrushColor and setting the opacity from there but nothing happens. I'm also trying INotifyPropertyChanged still to no avail. There are no errors either. The opacity just isn't affected. Here is the code of the overlay window that needs its opacity changed:
public partial class overlay : Window, INotifyPropertyChanged
{
public static overlay? thisOverlay;
DoubleAnimation fade = new DoubleAnimation(0, new Duration(TimeSpan.FromSeconds(5)));
public event PropertyChangedEventHandler? PropertyChanged;
private double _windowOpacity;
public double WindowOpacity
{
get => _windowOpacity;
set
{
if (_windowOpacity == value)
return;
_windowOpacity = value;
OnPropertyChanged();
}
}
public overlay()
{
InitializeComponent();
this.Loaded += Overlay_Loaded;
WindowOpacity = 0.2;
}
private void Overlay_Loaded(object sender, RoutedEventArgs e)
{
thisOverlay = this;
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public void setOpacity() // Function is ran outside of this class
{
this.WindowOpacity = 0.5; // This doesn't work
Trace.WriteLine("Works"); // This prints
}
and here is the XAML code for the window:
<Window x:Class="NAME.overlay"
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:NAME"
mc:Ignorable="d"
Title="overlay" Height="450" Width="800" WindowState="Maximized" WindowStyle="None" Topmost="True" AllowsTransparency="True" Opacity="{Binding WindowOpacity}" Visibility="Hidden">
</Window>

For the binding to your custom property to work you should set the DataContext:
public overlay()
{
InitializeComponent();
this.Loaded += Overlay_Loaded;
WindowOpacity = 0.2;
DataContext = this;
}

Related

ItemsSource Binding in UserControl doens't work [duplicate]

This question already has answers here:
Issue with DependencyProperty binding
(3 answers)
XAML binding not working on dependency property?
(1 answer)
Closed 3 years ago.
i am currently testing UserControls and therefore created this little App.
Main.xaml
<Grid>
<control:CustomInterfaceGrid Color="Green" Height="400" CustomItemsSource="{Binding Packages}"></control:CustomInterfaceGrid>
</Grid>
UserControl.xaml
<UserControl x:Class="App.Custom.CustomInterfaceGrid"
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"
xmlns:local="App.Custom"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
x:Name="SourceElement"
>
<Grid>
<ListBox x:Name="listView" Background="{Binding Color, ElementName=SourceElement}" ItemsSource="{Binding CustomItemsSource, ElementName=SourceElement}"></ListBox>
</Grid>
</UserControl>
CodeBehind from UserControl
public partial class CustomInterfaceGrid : UserControl, INotifyPropertyChanged
{
public CustomInterfaceGrid()
{
InitializeComponent();
DataContext = this;
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("Color", typeof(SolidColorBrush), typeof(CustomInterfaceGrid));
public SolidColorBrush Color
{
get; set;
}
public static readonly DependencyProperty CustomItemsSourceProperty =
DependencyProperty.Register("CustomItemsSource", typeof(IEnumerable<Object>), typeof(CustomInterfaceGrid));
public IEnumerable<Object> CustomItemsSource
{
get
{
return GetValue(CustomItemsSourceProperty) as IEnumerable<Object>;
}
set {
SetValue(CustomItemsSourceProperty, value);
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The problem is that my the color changes when I set it in Main, but it wont show the Packages from the List.
When i bind the Packages directly to a list in Main.xaml its alright. So the fault has to be somewhere else.
Hope you can help!
the main mistakes which leads to binding erros is unnecessary set DataContext. remove this line from constructor:
DataContext = this;
there is no need to implement INotifyPropertyChanged for UserControl which is also DependencyObject. DependencyProperties have internal mechanism to notify about changes. Remove OnPropertyChanged - declaration and all usages.
Speaking of DependencyProperties: public SolidColorBrush Color { get; set; } doesn't follow required pattern and has to be implemented with GetValue / SetValue method

How to create left and right swipes in WPF using Mouse? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm very new to C#.So, i'm trying create a simple swipe function in my WPF where if i swipe left or right, it goes to another wpf window. Please help me! I cannot find much resources online.
So my question is how to swipe using mouse in wpf application, so that i can switch between pages/window using mouse swipe.
I'm just trying to do like an image Carousel. I have so far followed this WPF image swipe to change image like in iOS
But, it doesn't swipe but zooms in and out when mouse is moved.
I am Using Pages but you can use window also.
1st. Create two Pages LeftPage.xaml, and RightPage.Xaml
and following code to MainWindow.xaml and MainWindows.xaml.cs
XAML
MainWindow
<Window x:Class="SOWPF.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:SOWPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
MouseDown="Window_MouseDown" MouseMove="Window_MouseMove">
<Grid>
<Frame x:Name="MainFrame" NavigationUIVisibility="Hidden" />
</Grid>
C#
public partial class MainWindow : Window
{
protected Point SwipeStart;
public MainWindow()
{
InitializeComponent();
MainFrame.Source = new Uri("LeftPage.xaml", UriKind.RelativeOrAbsolute);
}
private void Window_MouseDown(object sender, MouseEventArgs e)
{
SwipeStart = e.GetPosition(this);
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var Swipe = e.GetPosition(this);
//Swipe Left
if (SwipeStart != null && Swipe.X > (SwipeStart.X + 200))
{
// OR Use Your Logic to switch between pages.
MainFrame.Source = new Uri("LeftPage.xaml", UriKind.RelativeOrAbsolute);
}
//Swipe Right
if (SwipeStart != null && Swipe.X < (SwipeStart.X - 200))
{
// OR Use Your Logic to switch between pages.
MainFrame.Source = new Uri("RightPage.xaml", UriKind.RelativeOrAbsolute);
}
}
e.Handled = true;
}
}
I've created a Behavior so that the whole thing can be done without the need for any code behind. The good thing of using a Behavior is that you can reuse it wherever in your solution, unit test it to ensure it does as you want or extend it's functionality.
Main Window
<Window x:Class="TestWpfApplication.MainWindowView"
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:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:testWpfApplication="clr-namespace:TestWpfApplication"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<i:Interaction.Behaviors>
<testWpfApplication:SwipeBehavior TargetContentControl="{Binding ElementName=MainContentControl}" LeftUserControl="{Binding Path=LeftControl}" RightUserControl="{Binding Path=RightControl}" />
</i:Interaction.Behaviors>
<Grid>
<ContentControl Name="MainContentControl" />
</Grid>
</Window>
Main Window Code Behind
using System.Windows;
namespace TestWpfApplication
{
public partial class MainWindowView : Window
{
private readonly MainWindowViewModel _mainWindowViewModel = new MainWindowViewModel();
public MainWindowView()
{
InitializeComponent();
DataContext = _mainWindowViewModel;
}
}
}
Swipe Behavior
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace TestWpfApplication
{
public class SwipeBehavior : Behavior<Window>
{
public static readonly DependencyProperty TargetContentControlProperty = DependencyProperty.RegisterAttached("TargetContentControl", typeof(ContentControl), typeof(SwipeBehavior), new UIPropertyMetadata(null));
public static readonly DependencyProperty LeftUserControlProperty = DependencyProperty.RegisterAttached("LeftUserControl", typeof(UserControl), typeof(SwipeBehavior), new UIPropertyMetadata(null));
public static readonly DependencyProperty RightUserControlProperty = DependencyProperty.RegisterAttached("RightUserControl", typeof(UserControl), typeof(SwipeBehavior), new UIPropertyMetadata(null));
public static ContentControl GetTargetContentControl(DependencyObject dependencyObject)
{
return (ContentControl) dependencyObject.GetValue(TargetContentControlProperty);
}
public static void SetTargetContentControl(DependencyObject dependencyObject, ContentControl value)
{
dependencyObject.SetValue(TargetContentControlProperty, value);
}
public static ContentControl GetLeftUserControl(DependencyObject dependencyObject)
{
return (UserControl) dependencyObject.GetValue(LeftUserControlProperty);
}
public static void SetLeftUserControl(DependencyObject dependencyObject, UserControl value)
{
dependencyObject.SetValue(LeftUserControlProperty, value);
}
public static ContentControl GetRightUserControl(DependencyObject dependencyObject)
{
return (UserControl) dependencyObject.GetValue(RightUserControlProperty);
}
public static void SetRightUserControl(DependencyObject dependencyObject, UserControl value)
{
dependencyObject.SetValue(RightUserControlProperty, value);
}
private Point _swipeStart;
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.MouseDown += OnMouseDown;
AssociatedObject.MouseMove += OnMouseMove;
}
private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
_swipeStart = e.GetPosition(AssociatedObject);
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
var targetContentControl = GetValue(TargetContentControlProperty) as ContentControl;
if (targetContentControl == null)
{
return;
}
if (e.LeftButton == MouseButtonState.Pressed)
{
var swipe = e.GetPosition(AssociatedObject);
//Swipe Left
if (swipe.X > (_swipeStart.X + 200))
{
// OR Use Your Logic to switch between pages.
targetContentControl.Content = new LeftControl();
}
//Swipe Right
if (swipe.X < (_swipeStart.X - 200))
{
// OR Use Your Logic to switch between pages.
targetContentControl.Content = new RightControl();
}
}
e.Handled = true;
}
}
}
Main Window View Model
using System.Windows.Controls;
namespace TestWpfApplication
{
internal class MainWindowViewModel
{
public UserControl LeftControl { get; } = new LeftControl();
public UserControl RightControl { get; } = new RightControl();
}
}
Note: The LeftControl & RightControl are WPF User Controls in this example. Also you must reference System.Window.Interactivity in your project in order to use the Behavior class

UWP Binding. Something is not right

I'm new to C# and UWP. After many days of reading official microsoft docks and stackoverflow I still cannot understand what am I doing wrong.
Here is extremely simple test app.
I am trying to change grid's background on click. When application starts the grid's background is bg-1.jpg as expected. After click the value of property PicturePath have changed, but Grid's background have not.
What am I missing?
Here is a simple xaml page
<Page
x:Class="Test.Views.StartPage"
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"
mc:Ignorable="d">
<Grid PointerPressed="Grid_PointerPressed">
<Grid.Background>
<ImageBrush ImageSource="{Binding PicturePath, Mode=OneWay}" />
</Grid.Background>
</Grid>
</Page>
Code behind
public sealed partial class StartPage : Page
{
public StartPage()
{
this.InitializeComponent();
DataContext = new {
TestBackgroundClass.getInstance().PicturePath,
};
}
private void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
TestBackgroundClass.getInstance().PicturePath = "ms-appx:///Assets/bg-2.jpg";
}
}
and a singleton class
public class TestBackgroundClass : INotifyPropertyChanged
{
private static TestBackgroundClass instance;
private string _picturePath { get; set; }
public string PicturePath
{
get
{
return _picturePath;
}
set
{
_picturePath = value;
NotifyPropertyChanged();
}
}
public TestBackgroundClass()
{
_picturePath = "ms-appx:///Assets/bg-1.jpg"
}
public static TestBackgroundClass getInstance()
{
if (instance == null) instance = new TestBackgroundClass();
return instance;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

Wrong startup position of window, when SizeToContent is Manual, and Window.Top and Window.Left are databound

I've ran into a rather strange issue. It seems that as long as a window's SizeToContent is set to Manual and the dimensions and top/left properties are databound, the Presentation Framework won't update the location of the window when it is shown.
I have a Dialog Window-control which I use to display other UserControls within, and the behavior should be controlled by a ViewModel. Some dialogs I wish to display with SizeToContent.WidthAndHeight and ResizeMode.NoResize, and center them on the Owner-window. Other controls I wish to show in a dialog that can be resized, but opened with a specific size.
I made a test-project just to isolate the issue. Here is my Dialog:
<Window x:Class="DialogTests.Dialog"
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:DialogTests"
mc:Ignorable="d"
ResizeMode="CanResize"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner"
Width="{Binding Path=FormWidth, Mode=TwoWay}"
Height="{Binding Path=FormHeight, Mode=TwoWay}"
Top="{Binding Path=FormTop, Mode=TwoWay}"
Left="{Binding Path=FormLeft, Mode=TwoWay}"
Title="Dialog">
<StackPanel>
<Button Height="100">Button 1</Button>
<Button Width="100">Button 2</Button>
</StackPanel>
</Window>
public partial class Dialog : Window
{
public Dialog()
{
InitializeComponent();
this.DataContext = new DialogVm();
}
}
public class DialogVm : INotifyPropertyChanged
{
private double _formWidth;
private double _formHeight;
private double _formTop;
private double _formLeft;
public DialogVm()
{
FormWidth = 400;
FormHeight = 400;
}
public double FormWidth
{
get { return _formWidth; }
set
{
if (value.Equals(_formWidth)) return;
_formWidth = value;
OnPropertyChanged();
}
}
public double FormHeight
{
get { return _formHeight; }
set
{
if (value.Equals(_formHeight)) return;
_formHeight = value;
OnPropertyChanged();
}
}
public double FormTop
{
get { return _formTop; }
set
{
if (value.Equals(_formTop)) return;
_formTop = value;
OnPropertyChanged();
}
}
public double FormLeft
{
get { return _formLeft; }
set
{
if (value.Equals(_formLeft)) return;
_formLeft = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
The reason for having the Dialog databind to these properties is to save the state (dimensions and position), so that it can be used in cases where certain dialogs should be opened using these previous values.
In my main application I just open the dialog by pressing a button:
private void Button_Click(object sender, RoutedEventArgs e)
{
var dialog = new Dialog();
dialog.Owner = this;
dialog.ShowDialog();
}
If you run this, then everything works as expected. The dialog gets sized to fit the contents, and is placed in the center relative to the main application. The setters of FormWidth, FormHeight, FormTop and FormLeft get called. For the dimensions, it's first called from the constructor, then by the PresentationFramework.
However, if you go back to the Dialog xaml, and change SizeToContent="WidthAndHeight" to SizeToContent="Manual", the Dialog will be shown at the top left (0,0) of the screen. The dialog's dimensions are set in the view model contructor (400 x 400) and doesn't get called again (as expected). The issue is, the Setter methods of FormTop and FormLeft are never called. The expected behaviour is that the 400x400 window should be shown in the center of the Owner window.
If I change the Dialog.xaml to remove the databindings, and explicitly set the dimensions, it works as it should though:
<Window x:Class="DialogTests.Dialog"
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:DialogTests"
mc:Ignorable="d"
ResizeMode="CanResize"
SizeToContent="Manual"
WindowStartupLocation="CenterOwner"
Width="400"
Height="400"
Title="Dialog">
...
</Dialog>
Is this behavior a bug? Or is there something I am missing? Seems so strange that it works fine as long as SizeToContent is set to WidthAndHeight, or if I remove the bindings entirely and set the attributes in the xaml.
It depends on when the bindings are resolved and when the position of the window is set.
You could set the DataContext of the Dialog window before you call the InitializeComponent() method:
public Dialog()
{
this.DataContext = new DialogVm();
InitializeComponent();
}
Or set the WindowStartupLocation to Manual and calculate the values of your Left and Top source properties:
How do you center your main window in WPF?

One way dependency property changed notification

I'm trying to make a user control with a dependency property. I need to execute certain logic when the dependency property is changed from outside the usercontrol, but that logic shouldn't execute when the dependency property is changed from inside the user control. I have this small sample. I only want to execute certain logic when the value is set from mainwindow and not when it is set by clicking the checkbox. I don't know if PropertyChangedCallbackis the correct way, but this is what I have.
UserControl:
public partial class UserControl1 : UserControl
{
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(UserControl1), new PropertyMetadata(new PropertyChangedCallback(OnPropertyChanged)));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Only process the 5, don't process the 6
}
public UserControl1()
{
InitializeComponent();
}
private void checkBox_Click(object sender, RoutedEventArgs e)
{
MyProperty = 6;
}
}
UserControl xaml:
<UserControl x:Class="WpfApplication4.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="300" d:DesignWidth="300">
<Grid>
<CheckBox x:Name="checkBox" Click="checkBox_Click"/>
</Grid>
</UserControl>
MainWindow:
public partial class MainWindow : Window
{
public int MainWindowProperty { get; set; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
MainWindowProperty = 5;
}
}
Mainwindow xaml:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 MyProperty="{Binding MainWindowProperty}"/>
</Grid>
</Window>
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!disableProcessing)
{
// Only process the 5, don't process the 6
}
}
bool disableProcessing = false;
private void checkBox_Click(object sender, RoutedEventArgs e)
{
disableProcessing = true;
MyProperty = 6;
disableProcessing = false;
}

Categories

Resources