I want to be able to hide the left hand side of the screen and right hand side of the screen at the beginning of the program.
Then when the user presses create new button the left hand side of the screen becomes available so they can create the new item. Then when they press save it comes back to the middle datagrid only.
Then I want to add an event when the double click on the datagrid row (data is programmed in to the datagrid in the code) the right hand side of the screen becomes visible then when the button allocate is pressed the right hand side disappears again just leaving the datagrid.
I am fairly new to WPF so unsure whether this can be done or not. I am trying to do it in the same window at the moment I am making prototypes for my company and already have some that use separate windows. I had posted an image but am un able to post it as I am a new user.
To hide and show controls I would either recommend using expanders (as your comment says you've done) or Grids and setting their visibility as needed. If you want your side panels to appear over the datagrid then displaying them is just a matter of changing their visibility. If don't want obscure the DataGrid then you will need to change the visibility of the panels as well as the size of the window.
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<Grid>
<!-- DataGrid display -->
<Grid>
<StackPanel>
<Button Content="Add New" Click="OnAddNewButtonClick" Width="100"/>
<DataGrid ItemsSource="{Binding GridItems}" IsReadOnly="True" Name="dataGrid">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<EventSetter Event="MouseDoubleClick" Handler="OnRowDoubleClick"/>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</StackPanel>
</Grid>
<!-- Left column pops up over DataGrid -->
<Grid Name="LeftColumn" Visibility="Collapsed" Background="Red" Width="200" HorizontalAlignment="Left">
<StackPanel VerticalAlignment="Center">
<Button Content="Hide Column" Click="OnLeftColumnButtonClick"/>
</StackPanel>
</Grid>
<!-- Right Column expands screen size-->
<Grid Visibility="Collapsed" Name="RightColumn" Width="200" HorizontalAlignment="Right">
<StackPanel Background="Green" >
<TextBlock Text="Hidden Column"/>
<Button Content="Hide Panel" Click="OnRightColumnButtonClick"/>
</StackPanel>
</Grid>
</Grid>
</Window
C# - I know you're working in VB, but this was quicker for me. The code should be fairly self explanatory, but if you need a VB sample let me know:
public partial class MainWindow : Window
{
public ObservableCollection<Person> GridItems { get; set; }
private const double CollapsedWidth = 500;
private const double ExpandedWidth = 700;
public MainWindow()
{
DataContext = this;
GridItems = new ObservableCollection<Person>();
GridItems.Add(new Person { Name = "Foo", Age = 1 });
GridItems.Add(new Person { Name = "Bar", Age = 2 });
InitializeComponent();
Width = CollapsedWidth;
}
private void OnAddNewButtonClick(object sender, RoutedEventArgs e)
{
LeftColumn.Visibility = Visibility.Visible;
}
private void OnLeftColumnButtonClick(object sender, RoutedEventArgs e)
{
LeftColumn.Visibility = Visibility.Collapsed;
}
private void OnRowDoubleClick(object sender, MouseButtonEventArgs e)
{
Width = ExpandedWidth;
RightColumn.Visibility = Visibility.Visible;
}
private void OnRightColumnButtonClick(object sender, RoutedEventArgs e)
{
RightColumn.Visibility = Visibility.Collapsed;
Width = CollapsedWidth;
}
}
Related
`I am working on a WPF application (MVVM)
I have a user control(uc1) that has four buttons. cancel,accept,exit
I am going to use this control in multiple views.
I need to cancel button to revert the changes what user will make in propertygrig
user control:
<UserControl x:Class="WPF.CustomControl.RadPropertyWindowButtons"
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="45" d:DesignWidth="700">
<Grid>
<Grid Uid="radpropertybuttons" Height="39" VerticalAlignment="Bottom" Margin="74,0,-108,0">
<Button x:Name="Cancel"
Command="{Binding radpropertyCancel}" >
</Button>
<Button x:Name="Accept"
Command="{Binding radpropertyAccept}">
</Button>
<Button x:Name="Exit"
Command="{Binding radpropertyExit}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
</Button>
</Grid>
</Grid>
</UserControl>
view:
<Grid Height="564" VerticalAlignment="Top" >
<Grid HorizontalAlignment="Center">
<telerik:RadLayoutControl
Name="PropertyGridContainer"
Orientation="Vertical">
</telerik:RadLayoutControl>
</Grid>
<Grid VerticalAlignment="Bottom">
<customcontrol:RadPropertyWindowButtons x:Name="ucPropertyButtons" Height="44" VerticalAlignment="Top" HorizontalAlignment="Center" Loaded="RadPropertyWindowButtons_Loaded" />
</Grid>
</Grid>
in view model
public ICommand radpropertyCancel { get; set; }
radpropertyCancel = new ViewModelCommand(execradpropertyCancel);
private void execradpropertyCancel(object obj)
{
this.RevertToOriginalData();
}
how to clear the PropertyGridContainer and bind with the data that we get from RevertToOriginalData`
I do it like this if i do from code behind if i use click event but how to do it with command.
this._viewModel.RevertToOriginalData();
this.PropertyGridContainer.Items.Clear();
this.PropertyGridContainer.Items.Add(this._viewModel.myGrid);
this.ViewModel.IsDirty = false;
this._viewModel.myGrid is wrong design if myGrid is really a Grid ( a UI element). Your view model classes must never handle UI elements or participate in/implement UI logic.
Data changes are always handled outside the view (where the data lives). Layout on the other hand is always the domain of the view.
If you want to revert the layout changes made by the user, you must do this completely in the view (code-behind).
To accomplish this, a parent control (e.g., Window) that hosts both, the RadPropertyWindowButtons and the RadLayoutControl, should expose the related commands as routed commands.
Then in the command handlers you save (serialize) the layout before edit (or alternatively on accept/after edit) and restore (deserialize) it in case the edit procedure was cancelled. The RadLayoutControl exposes a related API to help with the serialization.
Now, that the implementation of the custom control no longer depends on the explicit view model class type, the RadPropertyWindowButtons has become fully reusable in any context.
In general, to enable reusability of controls they must express their (data) dependencies as dependency properties, that are later bound to the current DataContext. The internals of the reusable control simply bind to these dependency properties (instead of binding to an explicit DataContext type). Otherwise they are only "reusable" with a particular DataContext.
MainWindow.xaml.cs
partial class MainWindow : Window
{
public static RoutedUICommand CancelEditLayoutCommand { get; } = new RoutedUICommand(
"Cancel layout edit and revert to previous state",
nameof(MainWindow.CancelEditLayoutCommand),
typeof(MainWindow));
public static RoutedUICommand AcceptLayoutCommand { get; } = new RoutedUICommand(
"Accept the current layout",
nameof(MainWindow.AcceptLayoutCommand),
typeof(MainWindow));
private Dictionary<RadLayoutControl, bool> IsInEditModeTable { get; }
private string SerializedLayout { get; set; }
public MainWindow()
{
InitializeComponent();
this.IsInEditModeTable = new Dictionary<RadLayoutControl, bool>();
var cancelEditLayoutCommandBinding = new CommandBinding(MainWindow.CancelEditLayoutCommand, ExecuteCancelEditLayoutCommand, CanExecuteCancelEditLayoutCommand);
_ = this.CommandBindings.Add(cancelEditLayoutCommandBinding);
var acceptLayoutCommandBinding = new CommandBinding(MainWindow.AcceptLayoutCommand, ExecuteAcceptLayoutCommand, CanExecuteAcceptLayoutCommand);
_ = this.CommandBindings.Add(acceptLayoutCommandBinding);
}
private void CanExecuteCancelEditLayoutCommand(object sender, CanExecuteRoutedEventArgs e)
=> e.CanExecute = e.Parameter is RadLayoutControl targetControl
&& this.IsInEditModeTable.TryGetValue(targetControl, out bool isTargetControlInEditMode)
&& isTargetControlInEditMode;
private void ExecuteCancelEditLayoutCommand(object sender, ExecutedRoutedEventArgs e)
{
var targetControl = (RadLayoutControl)e.Parameter;
RestoreLayout(targetControl);
this.IsInEditModeTable[targetControl] = false;
}
private void CanExecuteAcceptLayoutCommand(object sender, CanExecuteRoutedEventArgs e)
=> e.CanExecute = e.Parameter is RadLayoutControl targetControl
&& this.IsInEditModeTable.TryGetValue(targetControl, out bool isTargetControlInEditMode)
&& isTargetControlInEditMode;
private void ExecuteAcceptLayoutCommand(object sender, ExecutedRoutedEventArgs e)
{
var targetControl = (RadLayoutControl)e.Parameter;
SaveLayout(targetControl);
this.IsInEditModeTable[targetControl] = false;
}
// Instead of handling the SelectionChanged event I recommend
// to introduce another routed command that allows the user to put the RadLayoutControl into edit mode (by setting the RadLayoutControl.IsInEditMode accordingly).
// Aside from an improved UX this would provide a better flow or trigger to kickoff the serialization
private void OnLayoutControlSelectionChanged(object sender, LayoutControlSelectionChangedEventArgs e)
{
var targetControl = sender as RadLayoutControl;
if (this.IsInEditModeTable.TryGetValue(targetControl, out bool isTargetControlInEditMode)
&& isTargetControlInEditMode)
{
return;
}
isTargetControlInEditMode = e.NewItem is not null;
if (isTargetControlInEditMode)
{
SaveLayout(targetControl);
}
this.IsInEditModeTable[targetControl] = isTargetControlInEditMode;
}
private void SaveLayout(RadLayoutControl targetControl)
=> this.SerializedLayout = targetControl.SaveToXmlString();
private void RestoreLayout(RadLayoutControl targetControl)
=> targetControl.LoadFromXmlString(this.SerializedLayout);
}
MainWindow.xaml
<Window>
<StackPanel>
<telerik:RadLayoutControl Name="PropertyGridContainer"
IsInEditMode="True"
telerik:RadLayoutControl.SerializationId="PropertyGridContainerID"
SelectionChanged="OnLayoutControlSelectionChanged" />
<customcontrol:RadPropertyWindowButtons TargetControl="{Binding ElementName=PropertyGridContainer}" />
</StackPanel>
</Window>
RadPropertyWindowButtons.xaml.cs
class RadPropertyWindowButtons
{
public RadLayoutControl TargetControl
{
get => (RadLayoutControl)GetValue(TargetControlProperty);
set => SetValue(TargetControlProperty, value);
}
public static readonly DependencyProperty TargetControlProperty = DependencyProperty.Register(
"TargetControl",
typeof(RadLayoutControl),
typeof(RadPropertyWindowButtons),
new PropertyMetadata(default));
}
RadPropertyWindowButtons.xaml
<UserControl>
<StackPanel>
<Button x:Name="Cancel"
Command="{x:Static local:MainWindow.CancelEditLayoutCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=TargetControl}" />
<Button x:Name="Accept"
Command="{x:Static local:MainWindow.AcceptLayoutCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=TargetControl}" />
</StackPanel>
</UserControl>
See Save/Load Layout for more advanced scenarios.
My Design Code like this:
<Grid HorizontalAlignment="Left" Height="42" VerticalAlignment="Top" Width="302" Margin="12,471,0,0" Background="{StaticResource AppBarItemForegroundThemeBrush}">
<TextBlock HorizontalAlignment="Left" Margin="6,6,0,0" TextWrapping="Wrap" Text="Change Color" VerticalAlignment="Top" Height="26" Width="137" FontSize="18" Foreground="Black" />
<Image HorizontalAlignment="Left" Height="33" Margin="163,3,0,0" VerticalAlignment="Top" Width="41" Source="Assets/c1-1.png" x:Name="c1" Tapped="c1_Tapped" />
<Image HorizontalAlignment="Left" Height="32" Margin="212,4,0,0" VerticalAlignment="Top" Width="45" Source="Assets/c3-1.png" x:Name="c2" Tapped="c2_Tapped" RenderTransformOrigin="0.825,0.5" />
<Image HorizontalAlignment="Left" Height="33" Margin="262,3,0,0" VerticalAlignment="Top" Width="40" Source="Assets/c2-1.png" x:Name="c3" Tapped="c3_Tapped" />
</Grid>
Code Behind code like this:
private void c1_Tapped(object sender, TappedRoutedEventArgs e)
{
Images = new ObservableCollection<string>();
Images.Add(#"Assets/02_perspective_img_1.png");
Images.Add(#"Assets/02_perspective_img_2.png");
Images.Add(#"Assets/02_perspective_img_3.png");
this.DataContext = this;
}
private void c2_Tapped(object sender, TappedRoutedEventArgs e)
{
Images = new ObservableCollection<string>();
Images.Add(#"Assets/03_perspective_img_1.png");
Images.Add(#"Assets/03_perspective_img_2.png");
Images.Add(#"Assets/03_perspective_img_3.png");
this.DataContext = this;
}
private void c3_Tapped(object sender, TappedRoutedEventArgs e)
{
Images = new ObservableCollection<string>();
Images.Add(#"Assets/01_perspective_img_1.png");
Images.Add(#"Assets/01_perspective_img_2.png");
Images.Add(#"Assets/01_perspective_img_3.png");
this.DataContext = this;
}
When tapped on particular image need to show that particular images.But not showing that .
only showing first clicked items images only.Please let me know how to change the collection.
i am binding that collection to flipview control in windows 8.
<FlipView.ItemTemplate>
<DataTemplate>
<Image HorizontalAlignment="Left" Source="{Binding}" Height="450" VerticalAlignment="Top" Width="792" x:Name="imagecontrol" Stretch="Fill"/>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I'm going under a few assumptions. One is that the FlipView control has it's ItemsSource binding to your Images property. If you are going to set the DataContext to yourself (the page in question) you need to do one of a few options.
One: Do not set Images to a new collection. You are using an ObservableCollection so take advantage of it. Clear the collection and add items back to it.
private void c3_Tapped(object sender, TappedRoutedEventArgs e)
{
Images.Clear();
Images.Add(#"Assets/01_perspective_img_1.png");
Images.Add(#"Assets/01_perspective_img_2.png");
Images.Add(#"Assets/01_perspective_img_3.png");
}
Two: Implement INotifyPropertyChanged in the page and fire the PropertyChanged event when you reset the Images property
private ICollection<string> _images;
public ICollection<string> Images
{
get { return _images; }
set
{
_images = value;
OnPropertyChanged("Images");
}
}
You will probably find that you will need more and more bindings. Because of this it is usually best to have a separate ViewModel class that holds your data.
the way Shawn is suggested is i will recommend but when i tested it in case of Windows 8 app page which is inherited by LayoutAwarePage then in that case - Firstly you got error that Page Can not Implement InotifypropertyChanged secondly when i Tested it With ObsevableCollection that time also it is not working..so i have come with this workaround for solving your problem. in this case you just have to update the itemsSource Property of your FlipView Control each time when you are updating your Image collection..
private void c1_Tapped(object sender, TappedRoutedEventArgs e)
{
Images = new ObservableCollection<string>();
Images.Add(#"Assets/02_perspective_img_1.png");
Images.Add(#"Assets/02_perspective_img_2.png");
Images.Add(#"Assets/02_perspective_img_3.png");
FlipviewControlName.ItemsSource = Images;
}
I know this is not the proper solution but i think i will solve your problem...
I ve a list from sharepoint and i collect from this list an hyperlink.
As i want my textbox to be like an hyperlink I ve added an event on mousedown to open this hyperlink, My concern is how to collect this hyperlink in the codebehind with the sender.
For the moment I've just hide this hyperlink in the tooltip maybe i can manage this differently any suggestion will be grantly appreciated.
My point so far, i don't know how to get this tooltip in the code behind.
Thanks
My XAML Code :
<ListBox Name="ListboxTips" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Picture}" Height="20"></Image>
<TextBlock MouseDown="TextBlock_MouseDown_URL" TextDecorations="Underline"
Margin="10,10,20,10" Width="160" TextWrapping="Wrap"
Text="{Binding Path=TitleTip}"
ToolTip="{Binding Path=URL}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My code behind :
foreach (SPSClient.ListItem item in TipsList)
{
var tips = new Tips();
tips.TitleTip = item.FieldValues.Values.ElementAt(1).ToString();
tips.App = item.FieldValues.Values.ElementAt(4).ToString();
// get the Hyperlink field URL value
tips.URL = ((FieldUrlValue)(item["LinkDoc"])).Url.ToString();
//should collect the description of the url
//tips.URLdesc = ((FieldUrlValue)(item["LinkDoc"])).Description.ToString();
tips.Picture = item.FieldValues.Values.ElementAt(4).ToString();
colTips.Add(tips);
}
ListboxTips.DataContext = colTips;
....
private void TextBlock_MouseDown_URL(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//string test = (ToolTip)(sender as Control).ToString();
System.Diagnostics.Process.Start("http://www.link.com");
//System.Diagnostics.Process.Start(test);
}
Thanks a lot,
You can just access the property directly. It is not elegant, but will work!
private void TextBlock_MouseDown_URL(object sender, MouseButtonEventArgs e)
{
TextBlock txtBlock = sender as TexBlock;
// just access the property
string url = txtBlock.ToolTip as string;
}
A more elegant approach might be to use a Button, Hyperlink or something that exposes a Command, so that you can bind the 'click' action to a command on your view model that performs the action you wish to execute.
usually you stick any data you want to trespass somewhere to Tag attribute.
<TextBlock .. Tag="{Binding Path=URL}" />
This is easily retrievable as a public property:
private void TextBlock_MouseDown_URL(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var tb = sender as TextBlock;
if(tb != null)
{
var neededUrl = tb.Tag;
}
}
I am switching content template of a ListViewItem at run mode to enable editting the item. For that I am showing a Panel with Ok and Cancel options and I need the user to select any of those option before moving to anotheritem. I want that Panel to behave like a modal Dialog.
Any suggestions?
Advanced Thanks,
Das
You could try listen to PreviewLostKeyboardFocus event and mark it as handled when you don't want to let focus go. Here is an example. We have two columns, and if you put focus into the first column you never go out from it until you click Release Focus button:
XAML
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Focus Sample" Height="300" Width="340">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GroupBox Header="Press Release Focus to leave">
<StackPanel PreviewLostKeyboardFocus="StackPanel_PreviewLostKeyboardFocus">
<TextBox/>
<Button Content="Release Focus"
Click="ReleaseFocusClicked"/>
</StackPanel>
</GroupBox>
<GroupBox Header="Try to switch focus here:"
Grid.Column="1">
<TextBox/>
</GroupBox>
</Grid>
</Window>
C#
using System.Windows;
using System.Windows.Input;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private bool _letGo;
public Window1()
{
InitializeComponent();
}
private void StackPanel_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
var uie = (UIElement) sender;
var newFocusDO = (DependencyObject)e.NewFocus;
if (!_letGo && !uie.IsAncestorOf(newFocusDO))
{
e.Handled = true;
}
}
private void ReleaseFocusClicked(object sender, RoutedEventArgs e)
{
_letGo = true;
}
}
}
I'm doing one extra check to ensure whether new focus target belongs to our panel. If we don't do this we never let focus leave from the currently focused element. It worth to mention that this approach doesn't keep user from clicking on other buttons in UI. It just holds focus.
Hope this helps.
Cheers, Anvaka.
I have a data template with a textbox and a button with some styles on it. I would like to have the button show the mouse over state when focus is on the textbox beside it. Is this possible?
I figure it would involve something like this. I can get the textbox through use of FindVisualChild and FindName. Then I can set the GotFocus event on the textbox to do something.
_myTextBox.GotFocus += new RoutedEventHandler(TB_GotFocus);
Here in TB_GotFocus I'm stuck. I can get the button I want to show the mouse over state of, but I don't know what event to send to it. MouseEnterEvent isn't allowed.
void TB_GotFocus(object sender, RoutedEventArgs e)
{
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(this.DataTemplateInstance);
DataTemplate template = myContentPresenter.ContentTemplate;
Button _button= template.FindName("TemplateButton", myContentPresenter) as Button;
_button.RaiseEvent(new RoutedEventArgs(Button.MouseEnterEvent));
}
I don't think it's possible to fake the event but you can force the button to render itself as if it had MouseOver.
private void tb_GotFocus(object sender, RoutedEventArgs e)
{
// ButtonChrome is the first child of button
DependencyObject chrome = VisualTreeHelper.GetChild(button, 0);
chrome.SetValue(Microsoft.Windows.Themes.ButtonChrome.RenderMouseOverProperty, true);
}
private void tb_LostFocus(object sender, RoutedEventArgs e)
{
// ButtonChrome is the first child of button
DependencyObject chrome = VisualTreeHelper.GetChild(button, 0);
chrome.ClearValue(Microsoft.Windows.Themes.ButtonChrome.RenderMouseOverProperty);
}
you need to reference PresentationFramework.Aero.dlll for this to work and then it will only work on Vista for the Aero theme.
If you want it to work for other themes you should make a custom controltemplate for each of the theme you want to support.
See http://blogs.msdn.com/llobo/archive/2006/07/12/663653.aspx for tips
As a follow up to jesperll's comment, I think you can get around making a custom template for each theme by dynamically setting the style to the one you want / null.
Here is my window, with the style defined (but not set to anything).
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="MouseOverStyle">
<Setter Property="Background">
<Setter.Value>Green</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="MyTextBox" Grid.Column="0" Text="Some Text" Margin="2" GotFocus="TextBox_GotFocus" LostFocus="MyTextBox_LostFocus"/>
<Button x:Name="MyButton" Grid.Column="1" Content="Button" Margin="2" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" />
</Grid>
Instead of setting the style via triggers in the template, you can use events in your .cs file like so:
...
public partial class Window1 : Window
{
Style mouseOverStyle;
public Window1()
{
InitializeComponent();
mouseOverStyle = (Style)FindResource("MouseOverStyle");
}
private void TextBox_GotFocus(object sender, RoutedEventArgs e) { MyButton.Style = mouseOverStyle; }
private void MyTextBox_LostFocus(object sender, RoutedEventArgs e) { MyButton.Style = null; }
private void Button_MouseEnter(object sender, MouseEventArgs e) { ((Button)sender).Style = mouseOverStyle; }
private void Button_MouseLeave(object sender, MouseEventArgs e) { ((Button)sender).Style = null; }
}
You get a reference to the style in the constructor and then dynamically set it / unset it. This way, you can define what you want your style to look like in Xaml, and you don't have to rely on any new dependencies.