My project contains 2 wpf apps and it seems like they are conflicting when i attempt to initialize component. The solution is called MainProject.V3
First wpf titled "Game1"
namespace MainProject.V3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void MainGame(object sender, RoutedEventArgs e)
{
}
Second is called "MainMenu":
namespace MainProject.V3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainWindow()
{
InitializeComponent();
}
}
}
Related
I have a form of Form1 class and a WPF user control inside it (inside ElementHost). How can I get the Form1 object from this control's code-behind?
Here is the code:
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void Btn_Click(object sender, RoutedEventArgs e)
{
// I'd like to access the form here
}
}
is there an issue with two way binding to the IsChecked property on a ToggleButton in .NET 3.5?
I have this XAML:
<ToggleButton
Name="tbMeo"
Command="{Binding FilterOnSatelliteTypeCmd}"
IsChecked="{Binding ShowMeoDataOnly, Mode=TwoWay}"
ToolTip="Show MEO data only">
<Image Source="../images/32x32/Filter_Meo.png" Height="16" />
</ToggleButton>
I have a ViewModel with the following property:
private bool _showMeoDataOnly;
public bool ShowMeoDataOnly
{
get { return _showMeoDataOnly; }
set
{
if (_showMeoDataOnly != value)
{
_showMeoDataOnly = value;
RaisePropertyChangedEvent("ShowMeoDataOnly");
}
}
}
If I click on the ToggleButton, the value of ShowMeoDataOnly is set accordingly. However, if I set ShowMeoDataOnly to true from code behind, the ToggleButton's visual state does not change to indicate that IsChecked is true. However, if I manually set the ToggleButton's IsChecked property instead of setting ShowMeoDataOnly to true in code behind, the button's visual state changes accordingly.
Unfortunately, switching over to .NET 4/4.5 is not an option right now, so I cannot confirm if this is a .NET 3.5 problem.
Is there anything wrong with my code?
Using a .NET 3.5 project to test this and the binding seems to work for me. Do you have INotifyPropertyChanged implemented on your ViewModel and use it appropriately when ShowMeoDataOnly gets set? You didn't post all your code, so it's hard to tell what the ViewModel is doing.
Here's what I have that worked. When I run the application, the button is selected. That's because ViewModelBase implements INotifyPropertyChanged and I do base.OnPropertyChanged("ShowMeoDataOnly") when the property is set.
MainWindow.xaml
<Window x:Class="ToggleButtonIsCheckedBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ToggleButtonIsCheckedBinding"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<ToggleButton IsChecked="{Binding ShowMeoDataOnly, Mode=TwoWay}">
Show Meo Data Only
</ToggleButton>
</Grid>
</Window>
MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ToggleButtonIsCheckedBinding
{
class MainWindowViewModel : ViewModelBase
{
bool _showMeoDataOnly;
public bool ShowMeoDataOnly {
get
{
return _showMeoDataOnly;
}
set
{
_showMeoDataOnly = value;
base.OnPropertyChanged("ShowMeoDataOnly");
}
}
public MainWindowViewModel()
{
ShowMeoDataOnly = true;
}
}
}
ViewModelBase.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;
namespace ToggleButtonIsCheckedBinding
{
/// <summary>
/// Base class for all ViewModel classes in the application.
/// It provides support for property change notifications
/// and has a DisplayName property. This class is abstract.
/// </summary>
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
#region Constructor
protected ViewModelBase()
{
}
#endregion // Constructor
#region DisplayName
/// <summary>
/// Returns the user-friendly name of this object.
/// Child classes can set this property to a new value,
/// or override it to determine the value on-demand.
/// </summary>
public virtual string DisplayName { get; protected set; }
#endregion // DisplayName
#region Debugging Aides
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // Debugging Aides
#region INotifyPropertyChanged Members
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected virtual void OnPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion // INotifyPropertyChanged Members
#region IDisposable Members
/// <summary>
/// Invoked when this object is being removed from the application
/// and will be subject to garbage collection.
/// </summary>
public void Dispose()
{
this.OnDispose();
}
/// <summary>
/// Child classes can override this method to perform
/// clean-up logic, such as removing event handlers.
/// </summary>
protected virtual void OnDispose()
{
}
#if DEBUG
/// <summary>
/// Useful for ensuring that ViewModel objects are properly garbage collected.
/// </summary>
~ViewModelBase()
{
string msg = string.Format("{0} ({1}) ({2}) Finalized", this.GetType().Name, this.DisplayName, this.GetHashCode());
System.Diagnostics.Debug.WriteLine(msg);
}
#endif
#endregion // IDisposable Members
}
}
(Note: ViewModelBase is pulled from this project: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx )
Verify that you DataContext is set up correctly.
DataContext = this;
... in your MainWindow.xaml.cs constructor is the easiest way, assuming the code we're looking at is in the MainWindow class.
I have an application that display different datasets (users, nationality, etc) on the screen using radOutlookbar.
I have manage to load the required views in each item to display the data with no problem.
I then built views for each dataset (users, nationality, etc) to display the details about each selected item (i.e:user) within the displayed datasets.
Case:
First, I need to display the respective view for each dataset when I click on it's item.
Second, The displayed view will have an option to edit/add the displayed details.
I want to achieve this scenario using state-base-navigation.
So,
I have a PRISM region inside ItemsControl with ItemsPanelTemplate of grid to host the loaded views, basically I load the views for each dataset.
Question,
How should I show/hide the respective view according to the selected dataset using VSM?
Question 2:
Should I be able to define another nested state inside the loaded view to enable the scenario of edit/add details for each view?
If someone have any idea to do this, will be of great help to have a starting code.
Best regards
May be there's other schemes to access VSM but I prefer to create AttachedProperty for it. Let me explain.
Here is VisualState manager
/// <summary>
/// Class will allow to change VisualSate on ViewModel via attached properties
/// </summary>
public static class VisualStateManagerEx
{
private static PropertyChangedCallback callback = new PropertyChangedCallback(VisualStateChanged);
/// <summary>
/// Gets the state of the visual.
/// </summary>
/// <param name="obj">The obj.</param>
/// <returns></returns>
public static string GetVisualState(DependencyObject obj)
{
return (string)obj.GetValue(VisualStateProperty);
}
/// <summary>
/// Sets the state of the visual.
/// </summary>
/// <param name="obj">The obj.</param>
/// <param name="value">The value.</param>
public static void SetVisualState(DependencyObject obj, string value)
{
obj.SetValue(VisualStateProperty, value);
}
/// <summary>
/// DP for 'VisualState'
/// </summary>
public static readonly DependencyProperty VisualStateProperty =
DependencyProperty.RegisterAttached(
"VisualState",
typeof(string),
typeof(VisualStateManagerEx),
new PropertyMetadata(null, VisualStateManagerEx.callback)
);
/// <summary>
/// Visuals the state changed.
/// </summary>
/// <param name="d">The d.</param>
/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
public static void VisualStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//Control changeStateControl = d as Control;
FrameworkElement changeStateControl = d as FrameworkElement;
if (changeStateControl == null)
throw (new Exception("VisualState works only on Controls type"));
if (Application.Current.Dispatcher.CheckAccess() == false)
{
// Wrong thread
System.Diagnostics.Debug.WriteLine("[VisualStateManagerEx] 'VisualStateChanged' event received on wrong thread -> re-route via Dispatcher");
Application.Current.Dispatcher.BeginInvoke(
//() => { VisualStateChanged(d, e); }
VisualStateManagerEx.callback
, new object[] { d, e }); //recursive
}
else
{
if (string.IsNullOrEmpty(e.NewValue.ToString()) == false)
{
//VisualStateManager.GoToState(changeStateControl, e.NewValue.ToString(), true);
VisualStateManager.GoToElementState(changeStateControl, e.NewValue.ToString(), true);
System.Diagnostics.Debug.WriteLine("[VisualStateManagerEx] Visual state changed to " + e.NewValue.ToString());
}
}
}
}
now - in XAML you attach it to your ViewModel like this:
<UserControl
xmlns:VSManagerEx=clr-namespace:Namespace.namespace;assembly=Assembly01"
VSManagerEx:VisualStateManagerEx.VisualState="{Binding Path=ViewModelVisualState, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
...
...
Now your VSM in XAML is bound to ViewModelVisualState property in ViewModelBase (or whatever will be bound to DataContext of this UserControl. So Actually in your ViewModelBase you using is like this:
/// <summary>
/// Base class for all 'view-models'
/// </summary>
[Export(typeof(ViewModelBase))]
public abstract class ViewModelBase : INavigationAware, INotifyPropertyChanged
{
private SynchronizationContext parentSyncContent;
#region VisualState
private string viewModelVisualState = string.Empty;
/// <summary>
/// Gets or sets the state of the view model visual.
/// </summary>
/// <value>
/// The state of the view model visual.
/// </value>
public virtual string ViewModelVisualState
{
get { return viewModelVisualState; }
set
{
viewModelVisualState = value;
RaisePropertyChanged(this, "ViewModelVisualState");
}
}
#endregion
/// <summary>
/// Raises the property changed.
/// </summary>
/// <param name="Sender">The sender.</param>
/// <param name="PropertyName">Name of the property.</param>
public void RaisePropertyChanged(object Sender, string PropertyName)
{
parentSyncContent.Post((state) =>
{
if (PropertyChanged != null)
PropertyChanged(Sender, new PropertyChangedEventArgs(PropertyName));
}, null);
}
...
...
So - in any ViewModel that inherit from this ViewModelBase could declare it own VMS states and manage them like this:
[Export(typeof(IViewModel1))
public ViewModel1 : ViewModelBase, IViewModel1
{
private const string VM_STATE_WORKING = "WorkingState";
internal void StartWorking()
{
this.ViewModelVisualState = VM_STATE_WORKING;
...
...
Regards question 2: No - you don't need to declare any additional Views inside anything. Read PRISM documentation about Navigation. There's great examples on how to create View/ViewModel that support various presentation logic.
Is this helpful to you ?
I am not familiar with using event handlers, and I was wondering if anyone had or could direct me to some code that shows how to use an event handler that will execute code on the Close/Closed event?
I know this can be done because of this answered question:
Run code on WPF form close
But I need some direction.
Thank you =)
It's just this XAML
<Window ... Closing="Window_Closing" Closed="Window_Closed">
...
</Window>
and code for both the Closing and Closed events
private void Window_Closing(object sender, CancelEventArgs e)
{
...
}
private void Window_Closed(object sender, EventArgs e)
{
....
}
If you want to do it all from code behind put this in your windows .cs file
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Closed += new EventHandler(MainWindow_Closed);
}
void MainWindow_Closed(object sender, EventArgs e)
{
//Put your close code here
}
}
}
If you want to do part in xaml and part in code behind do this in 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" Height="350" Width="525" Closed="MainWindow_Closed">
<Grid>
</Grid>
</Window>
and this in .cs
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
void MainWindow_Closed(object sender, EventArgs e)
{
//Put your close code here
}
}
}
The above to examples you can apply to any form in a xaml app. You can have multiple forms. If you want to apply code for the entire application exit process modify your app.xaml.cs file to this
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnExit(ExitEventArgs e)
{
try
{
//Put your special code here
}
finally
{
base.OnExit(e);
}
}
}
}
You can override the OnExit function in App.Xaml.cs like this:
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnExit(ExitEventArgs e)
{
//do your things
base.OnExit(e);
}
}
If you are using C# on Microsoft Visual Studio, the following worked for me.
In your Window.cs file
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Name_Space
{
public partial class Window : Form
{
public Window()
{
InitializeComponent();
//...
}
private void Window_Load(object sender, EventArgs e)
{
//...
}
private void Window_Closed(object sender, EventArgs e)
{
// Your code goes here...!
}
}
}
In your Window.Designer.cs file add this line to the following method
...
private void InitializeComponent()
{
...
//
// Window
//
...
this.Closed += new System.EventHandler(this.Window_Closed); // <-- add this line
}
...
I want to be able to route the double-click of a grid to a Command. I'm using Rx to simulate the double click but I can't figure out what control to attach the mouse handler to (the mouse event on the e.Row object in DataGrid.RowLoading event doesn't seem to work).
Anyone got any ideas?
Rx code for handling the Double click is as follows:
Observable.FromEvent<MouseButtonEventArgs>(e.Row, "MouseLeftButtonDown").TimeInterval().Subscribe(evt =>
{
if (evt.Interval.Milliseconds <= 300)
{
// Execute command on double click
}
});
I changed this code from handling MouseLeftButtonDown to MouseLeftButtonUp and it works now. The row must have something else handling the button down events.
Observable.FromEvent<MouseButtonEventArgs>(e.Row, "MouseLeftButtonUp").TimeInterval().Subscribe(evt =>
{
if (evt.Interval != TimeSpan.Zero && evt.Interval.TotalMilliseconds <= 300)
{
// Execute command on double click
}
});
Full source code is included below:
CommandBehaviorBase.cs
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
/// <summary>
/// Provides the base implementation of all Behaviors that can be attached to a <see cref="FrameworkElement"/> which trigger a command.
/// </summary>
/// <typeparam name="T">The type of control this behavior can be attached to, must derive from <see cref="FrameworkElement"/>.</typeparam>
public abstract class CommandBehaviorBase<T> : Behavior<T> where T : FrameworkElement
{
#region Constants and Fields
/// <summary>The DependencyProperty backing store for CommandParameter. This enables animation, styling, binding, etc...</summary>
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register(
"CommandParameter",
typeof(object),
typeof(CommandBehaviorBase<T>),
new PropertyMetadata(null, OnCommandParameterPropertyChanged));
/// <summary>The DependencyProperty backing store for Command. This enables animation, styling, binding, etc...</summary>
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
"Command", typeof(ICommand), typeof(CommandBehaviorBase<T>), new PropertyMetadata(null));
#endregion
/// <summary>
/// Gets or sets the command to execute
/// </summary>
public ICommand Command
{
get
{
return (ICommand)this.GetValue(CommandProperty);
}
set
{
this.SetValue(CommandProperty, value);
}
}
/// <summary>
/// Gets or sets the command parameter to execute with.
/// </summary>
public object CommandParameter
{
get
{
return this.GetValue(CommandParameterProperty);
}
set
{
this.SetValue(CommandParameterProperty, value);
}
}
/// <summary>
/// Gets or sets the command binding path (Hack for SL3).
/// </summary>
/// <remarks>This is a hack to overcome the fact that we cannot
/// bind to the Command dependency property due to a limitation in Silverlight 3.0
/// This shouldn't be necessary as in Silverlight 4.0 <see cref="DependencyObject"/> supports data binding hooray!</remarks>
public string CommandPath { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this mapping is currently enabled.
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Implements the logic that disables the key mapping based on whether the command can be executed.
/// </summary>
/// <summary>
/// Updates the target object's IsEnabled property based on the commands ability to execute.
/// </summary>
public virtual void UpdateEnabledState()
{
if (this.Command == null && !string.IsNullOrEmpty(this.CommandPath))
{
this.Command = this.AssociatedObject.DataContext.GetPropertyPathValue<ICommand>(this.CommandPath, null);
}
if (this.AssociatedObject == null)
{
this.Command = null;
this.CommandParameter = null;
}
else if (this.Command != null)
{
this.IsEnabled = this.Command.CanExecute(this.CommandParameter);
}
}
/// <summary>
/// Executes the command, if it's set, providing the <see cref="CommandParameter"/>
/// </summary>
protected virtual void ExecuteCommand()
{
if (this.Command != null)
{
this.Command.Execute(this.CommandParameter);
}
}
/// <summary>
/// Attaches to the target <see cref="FrameworkElement"/> and sets up the command.
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
this.UpdateEnabledState();
}
/// <summary>
/// Raised when the command parameter changes, re-evaluates whether the Command can execute
/// </summary>
/// <param name="sender">The KeyCommandBehavior that command parameter changed for.</param>
/// <param name="args">The parameter is not used.</param>
private static void OnCommandParameterPropertyChanged(
DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
((CommandBehaviorBase<T>)sender).UpdateEnabledState();
}
}
DoubleClickCommandBehavior.cs
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
/// <summary>
/// Provides behavior for any clickable control and will execute a command when the control is double clicked.
/// Does not disable the control if the command cannot be executed.
/// </summary>
public class DoubleClickCommandBehavior : CommandBehaviorBase<FrameworkElement>
{
#region Constants and Fields
/// <summary>
/// Stores the observable that subscribes to click events.
/// </summary>
private IDisposable observable;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the DoubleClickCommandBehavior class.
/// </summary>
public DoubleClickCommandBehavior()
{
// Default double-click interval is 220 milliseconds.
this.Interval = 220;
}
#endregion
/// <summary>
/// Gets or sets the double click interval in milliseconds.
/// </summary>
public int Interval
{
get;
set;
}
/// <summary>
/// Subscribes to the MouseLeftButtonUp of the data grid and times the intervals between the events,
/// if the time between clicks is less than the configured interval the command is executed.
/// </summary>
/// <remarks>Originally attached to MouseLeftButtonDown but the events were not firing.</remarks>
protected override void OnAttached()
{
base.OnAttached();
this.observable =
Observable.FromEvent<MouseButtonEventArgs>(this.AssociatedObject, "MouseLeftButtonUp").TimeInterval().
Subscribe(
evt =>
{
if (evt.Interval != TimeSpan.Zero && evt.Interval.TotalMilliseconds <= this.Interval)
{
this.UpdateEnabledState();
this.ExecuteCommand();
}
});
}
/// <summary>
/// Disposes of the observable
/// </summary>
protected override void OnDetaching()
{
if (this.observable != null)
{
this.observable.Dispose();
this.observable = null;
}
base.OnDetaching();
}
}
I'm having similar problems (though not using Rx to handle the double click, instead using a generic DoubleClickTrigger). My specific problem is more related to the fact that I'm not sure how or where to hook up my trigger.
I've tried something like the following:
<data:DataGrid.Resources>
<ControlTemplate x:Key="rowTemplate" TargetType="data:DataGridRow">
<data:DataGridRow>
<fxui:Interaction.Triggers>
<fxui:DoubleClickTrigger>
<Interactivity:InvokeCommandAction Command="{Binding Source={StaticResource selectCommand}}" CommandParameter="{Binding}"/>
</fxui:DoubleClickTrigger>
</fxui:Interaction.Triggers>
</data:DataGridRow>
</ControlTemplate>
</data:DataGrid.Resources>
<data:DataGrid.RowStyle>
<Style TargetType="data:DataGridRow">
<Setter Property="Template" Value="{StaticResource rowTemplate}"/>
</Style>
</data:DataGrid.RowStyle>
With no luck.