I have a requirement to make a Cancel Button that will rollback all changes since the last context save. I got it were the rollback worked on a button click. However, the DataGridView didn't reflect the change. If I quit the program I can see that no data was changed.
I got the following form to work ( I don't see any errors in the Output window ) however, everything I read says to wrap the context in a using statement. Does that still apply in this situation? I have used Rollback and commit in a save method try/catch but this plane ole' doesn't look right. What if I spawn to another Form, will it add to the current transaction or not?
/// <summary>
/// </summary>
public partial class Form2 : Form
{
/// <summary>
/// </summary>
private TestContext _context;
/// <summary>
/// </summary>
private DbContextTransaction _transaction;
/// <summary>
/// </summary>
public Form2()
{
InitializeComponent();
}
/// <summary>
/// </summary>
/// <param name="e"></param>
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
_transaction.Rollback();
_context.Dispose();
}
/// <summary>
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_context = new TestContext();
_transaction = _context.Database.BeginTransaction();
SetupDataGridView();
}
/// <summary>
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCancel_Click(object sender, EventArgs e)
{
_transaction.Rollback();
_context = new TestContext();
SetupDataGridView();
_transaction = _context.Database.BeginTransaction();
}
/// <summary>
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSave_Click(object sender, EventArgs e)
{
Validate();
PersonDataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
_context.SaveChanges();
_transaction.Commit();
PersonBindingSource.ResetBindings(true);
_transaction = _context.Database.BeginTransaction();
}
/// <summary>
/// </summary>
private void SetupDataGridView()
{
_context.People.Load();
ObservableCollection<Person> people = _context.People.Local;
PersonBindingSource.DataSource = people.ToBindingList();
PersonBindingSource.RaiseListChangedEvents = true;
PersonDataGridView.AutoGenerateColumns = false;
PersonDataGridView.DataSource = PersonBindingSource;
}
}
Related
Most of the time we face problem in handling the ItemChange or SelectionChanged for tree, After a lot of struggle i found a working solution for myself. Below is the answer
With Below attached property When ever tree Item is selected or selection changed it directly raises the command on that object
public class ControlBehaviour
{
private static IDictionary<object, ICommand> dataContextCommandMap = new Dictionary<object, ICommand>();
private static IDictionary<FrameworkElement, object> elementDataConextMap = new Dictionary<FrameworkElement, object>();
/// <summary>
///
/// </summary>
public static readonly DependencyProperty ControlEventProperty =
DependencyProperty.RegisterAttached("ControlEvent", typeof(RoutedEvent), typeof(ControlBehaviour),
new PropertyMetadata(OnTreeviewSelectionChanged));
/// <summary>
///
/// </summary>
/// <param name="target"></param>
/// <param name="value"></param>
public static void SetControlEvent(DependencyObject target, object value)
{
target.SetValue(ControlEventProperty, value);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <returns></returns>
public static RoutedEvent GetControlEvent(DependencyObject sender)
{
return sender.GetValue(ControlEventProperty) as RoutedEvent;
}
/// <summary>
/// Command to be executed
/// </summary>
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand),
typeof(ControlBehaviour), new PropertyMetadata(CommandChanged));
/// <summary>
/// Set ICommand to the dependency object
/// </summary>
/// <param name="target">dependency object</param>
/// <param name="value">I command</param>
public static void SetCommand(DependencyObject target, object value)
{
target.SetValue(CommandProperty, value);
}
/// <summary>
/// Get ICommand to the dependency object
/// </summary>
/// <param name="sender">dependency object</param>
/// <returns>ICommand of the dependency object</returns>
public static ICommand GetCommand(DependencyObject sender)
{
return sender.GetValue(CommandProperty) as ICommand;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnTreeviewSelectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (sender != null)
{
TreeView element = sender as TreeView;
if (element != null)
{
if (e.NewValue != null)
{
element.SelectedItemChanged += Handler;
}
if (e.OldValue != null)
{
element.SelectedItemChanged -= Handler;
}
}
}
}
/// <summary>
/// ICommand Changed
/// </summary>
/// <param name="sender">dependency object</param>
/// <param name="e">dependency args</param>
private static void CommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (sender != null)
{
FrameworkElement cntrl = sender as FrameworkElement;
if (cntrl != null && cntrl.DataContext != null)
{
if (e.NewValue != null)
{
ICommand cmd = e.NewValue as ICommand;
if (cmd != null)
{
elementDataConextMap[cntrl] = cntrl.DataContext;
dataContextCommandMap[cntrl.DataContext] = cmd;
}
}
cntrl.Unloaded += FrameworkElementUnloaded;
}
}
}
/// <summary>
/// Framework element unload, Clears the removes the ICommand
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void FrameworkElementUnloaded(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null && elementDataConextMap.ContainsKey(element))
{
dataContextCommandMap.Remove(elementDataConextMap[element]);
elementDataConextMap.Remove(element);
}
}
/// <summary>
/// Routed Event Handler
/// </summary>
/// <param name="sender">sender</param>
/// <param name="e">EventArgs</param>
static void Handler(object sender, EventArgs e)
{
TreeView treeView = sender as TreeView;
if (treeView != null && treeView.SelectedItem != null && dataContextCommandMap.ContainsKey(treeView.SelectedItem)
&& dataContextCommandMap[treeView.SelectedItem].CanExecute(treeView.SelectedItem))
{
dataContextCommandMap[treeView.SelectedItem].Execute(treeView.SelectedItem);
}
}
}
Below is the XMAL which uses the above Attached property
<TreeView Grid.Row="1" Background="Transparent" ItemsSource="{Binding Directories}" Margin="0,10,0,0" Name="FolderListTreeView"
Height="Auto" HorizontalAlignment="Stretch" Width="300" local:ControlBehaviour.ControlEvent="TreeView.SelectedItemChanged" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:FileSystem}" ItemsSource="{Binding SubDirectories}">
<Label Content="{Binding Path= Name}" Name="NodeLabel" local:ControlBehaviour.Command="{Binding OnSelect}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Below is FileSystem class which is bound in Xaml
/// <summary>
/// Implementation of file system class
/// </summary>
public class FileSystem :BindableBase, IFileSystem, IEnumerable //BindableBase is base class which implemets INotifyPropertyChanged
{
#region Private members
private ObservableCollection<IFileSystem> subDirectoriesField;
private ObservableCollection<IFileSystem> filesField;
#endregion
#region Public properties
/// <summary>
/// Gets and sets all the Files in the current folder
/// </summary>
public ObservableCollection<IFileSystem> SubDirectories
{
get
{
return subDirectoriesField;
}
set
{
if (subDirectoriesField != value)
{
subDirectoriesField = value;
NotifyPropertyChanged("SubDirectories");
}
}
}
/// <summary>
/// Gets and sets all the files in the current folder
/// </summary>
public ObservableCollection<IFileSystem> Files
{
get
{
return filesField;
}
set
{
if (filesField != value)
{
filesField = value;
RaisePropertyChanged("Files");
}
}
}
/// <summary>
/// Gets or sets the type of the file
/// </summary>
public FileSystemType FileType
{
get;
set;
}
/// <summary>
/// Gets or sets the size of the file
/// </summary>
public long Size
{
get;
set;
}
/// <summary>
/// Gets or sets name of the file system
/// </summary>
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets full path of the file system
/// </summary>
public string FullPath
{
get;
set;
}
/// <summary>
/// object of parent, null if the current node is root
/// </summary>
public FileSystem Parent
{
get;
set;
}
/// <summary>
/// Returns ICommand
/// </summary>
public ICommand OnSelect
{
get
{
return new Command_R(Execute);//Command_R is implemention of your ICommand
}
}
#endregion
#region Constructor
/// <summary>
/// Constructor
/// </summary>
/// <param name="path">path of the folder</param>
/// <param name="parent">object of the parent</param>
public FileSystem(string fullPath, FileSystem parent, FileSystemType
type = FileSystemType.Directory)
{
Name = fullPath != null ? GetNameFileName(fullPath) : fullPath;
FullPath = fullPath;
Parent = parent;
FileType = type;
FilesAndSubDirectoriesDetails(fullPath);
}
#endregion
#region Public methods
/// <summary>
/// Updates the file size if there is a change
/// </summary>
/// <param name="deleteFilzeSize"></param>
public void UpdateFileSize(long deleteFilzeSize)
{
UpdatePredecessor(this, deleteFilzeSize);
}
/// <summary>
/// Gets the enumeration list
/// </summary>
/// <returns>returns the enumeration list</returns>
public IEnumerator GetEnumerator()
{
return SubDirectories.GetEnumerator();
}
#endregion
#region Private methods
/// <summary>
/// Finds the details of the files and sub directories
/// </summary>
/// <param name="fullPath"></param>
private void FilesAndSubDirectoriesDetails(string fullPath)
{
if (FileType.Equals(FileSystemType.Directory))
{
AddFilesAndSubDirectories(fullPath);
CalculateDirectorySize();
}
else
{
//Write code to calcuate the File Size
//Size = FileInfo.GetSize(fullPath);
}
}
/// <summary>
/// Finds and adds the files and sub directories
/// </summary>
/// <param name="fullPath"></param>
private void AddFilesAndSubDirectories(string fullPath)
{
string[] subDirectories = Directory.GetDirectories(fullPath);
SubDirectories = new ObservableCollection<IFileSystem>();
foreach (string directory in subDirectories)
{
SubDirectories.Add(new FileSystem(directory, this));
}
Files = new ObservableCollection<IFileSystem>();
string[] files = File.GetFiles(fullPath);
foreach (string fileName in files)
{
Files.Add(new FileSystem(fileName, this, FileSystemType.File));
}
}
/// <summary>
/// Calculates the current directory size
/// </summary>
private void CalculateDirectorySize()
{
foreach (FileSystem directory in SubDirectories)
{
Size += directory.Size;
}
foreach (FileSystem file in Files)
{
Size += file.Size;
}
}
/// <summary>
/// Updates the file size of the predecessors
/// </summary>
/// <param name="currentNode">current node</param>
/// <param name="deleteFilzeSize">file to be updated</param>
private void UpdatePredecessor(FileSystem currentNode, long deletedFilzeSize)
{
if (currentNode != null)
{
currentNode.Size -= deletedFilzeSize;
UpdatePredecessor(currentNode.Parent, deletedFilzeSize);
}
}
/// <summary>
/// Executes ICommand
/// </summary>
/// <param name="parameter">parameter</param>
private void Execute(object parameter)
{
//Do your Job
MessageBox.Show(FullPath);
}
#endregion
}
And the interface for the class
/// <summary>
/// Type of the file
/// </summary>
public enum FileSystemType
{
/// <summary>
/// File
/// </summary>
File,
/// <summary>
/// Directory
/// </summary>
Directory
}
/// <summary>
/// Interface for File system
/// </summary>
public interface IFileSystem
{
/// <summary>
/// Gets or sets file type
/// </summary>
FileSystemType FileType
{
get;
set;
}
/// <summary>
/// Gets or sets the file size
/// </summary>
long Size
{
get;
set;
}
/// <summary>
/// Gets or sets name of the file system
/// </summary>
string Name
{
get;
set;
}
/// <summary>
/// Gets or sets full path of the file system
/// </summary>
string FullPath
{
get;
set;
}
}
This question already has answers here:
What's the best way to pass event to ViewModel?
(3 answers)
Closed 8 years ago.
I am trying to find a simple example on how to bind some TextBox events (PreviewTextInput and PreviewKeyDown) to a Commands, however I can't find any clear example and all the exmaples I found so far enforce me to use some MVVM framework (Light toolkit, Prism, etc.), however currently I don't want to use a framework because I want to understand more deeply how the business works.
Can anyone please supply a simple example on how this can be achieved?
Is it absolutely necessary to use MVVM framework?
Thanks in advance.
The easy way is to attach a common event handler to the event in XAML, and invoke the Command in code-behind. Such an event handler could look like the following:
private void TextBox_OnTextChanged(object sender, EventArgs e)
{
var viewmodel = this.DataContext as MyViewmodel;
if (viewmodel != null)
{
viewmodel.SomeCommand.Execute();
}
}
An alternative that works without any code in the code-behind (but is a bit tricky to implement, and works only on .NET 4.5) is to implement your own MarkupExtension, such that you can code something like
<TextBox TextChanged="{myMarkupExtension:CommandBinding SomeCommand]">...</TextBox>
There are a few articles out there describing this approach, for example this one
You can inherit TextBox and implement ICommandSource. I have done the same, my implementation looked like this. You should be able to extend this to work on PreviewTextInput.
public class CommandTextBox : TextBox, ICommandSource
{
private bool _canExecute;
private EventHandler _canExecuteChanged;
/// <summary>
/// DependencyProperty for Command property.
/// </summary>
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandTextBox), new PropertyMetadata(OnCommandChanged));
/// <summary>
/// Gets or sets the command to invoke when the enter key is pressed.
/// </summary>
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
/// <summary>
/// DependencyProperty for CommandParameter property.
/// </summary>
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandTextBox));
/// <summary>
/// Gets or sets the parameter to pass to the Command property.
/// </summary>
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
/// <summary>
/// Gets or sets a value that indicates whether the command resets the text property.
/// </summary>
public bool CommandResetsText { get; set; }
/// <summary>
/// DependencyProperty for CommandTarget property.
/// </summary>
public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(CommandTextBox));
/// <summary>
/// Gets or sets the element on which to raise the specified command.
/// </summary>
public IInputElement CommandTarget
{
get { return (IInputElement)GetValue(CommandTargetProperty); }
set { SetValue(CommandTargetProperty, value); }
}
/// <summary>
/// Gets a value that becomes the return value of
/// System.Windows.UIElement.IsEnabled in derived classes.
/// </summary>
protected override bool IsEnabledCore
{
get { return base.IsEnabledCore && _canExecute; }
}
/// <summary>
/// Command dependency property change callback.
/// </summary>
/// <param name="d">Dependency Object</param>
/// <param name="e">Event Args</param>
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CommandTextBox tb = (CommandTextBox)d;
tb.HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue);
}
/// <summary>
/// If Command is defined, pressing the enter key will invoke the command;
/// Otherwise, the textbox will behave normally.
/// </summary>
/// <param name="e">Provides data about the event.</param>
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Enter && Command != null)
{
RoutedCommand command = Command as RoutedCommand;
if (command != null)
command.Execute(CommandParameter, CommandTarget);
else
Command.Execute(CommandParameter);
if (CommandResetsText)
this.Text = String.Empty;
}
}
/// <summary>
/// Add a command to the Command Property.
/// </summary>
/// <param name="command">Command</param>
private void AddCommand(ICommand command)
{
var handler = new EventHandler(CanExecuteChanged);
_canExecuteChanged = handler;
if (command != null)
command.CanExecuteChanged += _canExecuteChanged;
}
private void CanExecuteChanged(object sender, EventArgs e)
{
if (Command != null)
{
RoutedCommand command = Command as RoutedCommand;
// If a RoutedCommand.
if (command != null)
_canExecute = command.CanExecute(CommandParameter, CommandTarget);
else
_canExecute = Command.CanExecute(CommandParameter);
}
CoerceValue(UIElement.IsEnabledProperty);
}
/// <summary>
/// Add a new command to the Command Property.
/// </summary>
/// <param name="oldCommand">Old Command</param>
/// <param name="newCommand">New Command</param>
private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
{
// If oldCommand is not null, then we need to remove the handlers.
if (oldCommand != null)
RemoveCommand(oldCommand);
AddCommand(newCommand);
}
/// <summary>
/// Remove a command from the Command Property.
/// </summary>
/// <param name="command">Command</param>
private void RemoveCommand(ICommand command)
{
EventHandler handler = CanExecuteChanged;
command.CanExecuteChanged -= handler;
}
}
When I try to launch the View from the constructor of anothers Views ViewModel i get the Error :
Cannot perform this operation while dispatcher processing is suspended
ViewModel of My View from Where i am launching (a UserControl)
public class ExecutionViewModel : BaseViewModel
{
#region Member Variables
/// <summary>
/// Logger
/// </summary>
private static readonly ILog log =
LogManager.GetLogger(typeof(ConfigurationViewModel));
#endregion
#region Properties
/// <summary>
/// Get/Set ExitCommand
/// </summary>
public ICommand ExitCommand { get; set; }
/// <summary>
/// Command To Launch Report a Problem
/// </summary>
public ICommand ReportAProblemView { get; set; }
/// <summary>
/// Command To Launch About
/// </summary>
public ICommand AboutView { get; set; }
/// <summary>
/// LaunchNavigationkeyViewCommamd
/// </summary>
public ICommand LaunchSelectionScreenCommamd { get; set; }
#endregion
# region Constructor
/// <summary>
/// Default Constructor
/// </summary>
public ExecutionViewModel()
{
ExitCommand = new RelayCommand(ExitFromApplication);
ReportAProblemView = new RelayCommand(LaunchReportAProblemView,
CanLaunchReportAProblemView);
AboutView = new RelayCommand(LaunchAboutView, CanLaunchAboutView);
LaunchNavigationkeyViewCommamd = new RelayCommand(LaunchNavigationkeyView);
LaunchSelectionScreenCommamd =
new RelayCommand(LaunchSelectionScreenView);
LaunchMenuConfigViewCommamd = new RelayCommand(LaunchMenuConfigView);
Messenger.UnRegister(this);
Messenger.Register(this);
UpdateStatusBar();
//Here i am Trying to perfrom Somecheck and Launch View if Needed
InitiateStartUpValidations();
}
Private void InitiateStartUpValidations()
{
if (Utility.IsStringNullOrEmpty(DOEConfigFileName))
{
PasswordViewModel passwordViewModel = new PasswordViewModel(FileDialogModes.Open) { ShowPasswordBox = false };
// Launching View using Messenger
// This Gives an error
Messenger.NotifyColleagues(MessengerMessages.LAUNCH_FILE_SELECT_VIEW, passwordViewModel);
}
}
/// <summary>
/// LaunchMenuConfigView
/// </summary>
/// <param name="obj"></param>
private void LaunchMenuConfigView(object obj)
{
log.Debug("LaunchMenuConfigView" + BaseModel.FUNCTION_ENTERED_LOG);
MenuConfigViewModel menuConfigViewModel =
new MenuConfigViewModel();
Messenger.NotifyColleagues(MessengerMessages.LAUNCH_VIEW_MENU_CONFIG, menuConfigViewModel);
log.Debug("LaunchMenuConfigView" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// LaunchSelectionScreenView
/// </summary>
/// <param name="obj"></param>
private void LaunchSelectionScreenView(object obj)
{
log.Debug("LaunchSelectionScreenView" + BaseModel.FUNCTION_ENTERED_LOG);
SelectionScreenViewModel selectionScreenViewModel =
new SelectionScreenViewModel();
Messenger.NotifyColleagues(MessengerMessages.LAUNCH_SELECTIONSCREEN_VIEW, selectionScreenViewModel);
log.Debug("LaunchSelectionScreenView" + BaseModel.FUNCTION_EXIT_LOG);
}
# endregion
# region Private Methods
/// <summary>
/// CanLaunchSelectPageDefinitionView
/// </summary>
/// <param name="obj"></param>
private void CanLaunchSelectPageDefinitionView(object obj)
{
}
/// <summary>
/// LaunchNavigationkeyView
/// </summary>
private void LaunchNavigationkeyView(object obj)
{
log.Debug("LaunchNavigationkeyView" + BaseModel.FUNCTION_ENTERED_LOG);
UtilityViewModel utilityViewModel = new UtilityViewModel();
Messenger.NotifyColleagues(MessengerMessages.LAUNCH_VIEW_NAVIGATIONKEY, utilityViewModel);
log.Debug("LaunchNavigationkeyView" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// Update the progressbar status message
/// </summary>
private void UpdateStatusBar()
{
log.Debug("UpdateStatusBar" + BaseModel.FUNCTION_ENTERED_LOG);
UpdateProgressbarStatus(string.Empty, false);
log.Debug("UpdateStatusBar" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// CanLaunchAboutView
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private bool CanLaunchAboutView(object obj)
{
return true;
}
/// <summary>
/// LaunchAboutView
/// </summary>
/// <param name="obj"></param>
private void LaunchAboutView(object obj)
{
Messenger.NotifyColleagues(MessengerMessages.LAUNCH_ABOUT_VIEW, "About View");
}
/// <summary>
/// CanLaunchReportAProblemView
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private bool CanLaunchReportAProblemView(object obj)
{
return true;
}
/// <summary>
/// LaunchReportAProblemView
/// </summary>
/// <param name="obj"></param>
private void LaunchReportAProblemView(object obj)
{
Messenger.NotifyColleagues(MessengerMessages.LAUNCH_REPORT_A_PROBLEM_VIEW, "Report A Problem");
}
/// <summary>
/// </summary>
/// <param name = "obj"></param>
private void ExitFromApplication(object obj)
{
log.Debug(BaseModel.FUNCTION_ENTERED_LOG);
Messenger.NotifyColleagues(MessengerMessages.EXIT_APPLICATION, obj);
log.Debug(BaseModel.FUNCTION_EXIT_LOG);
}
# endregion
}
Code behing of my MainView (Where all the Views are Registered)
#region class - MainView
/// <summary>
/// Interaction logic for MainView.xaml
/// </summary>
public partial class MainView : BaseWindowClass
{
# region Member Variables
/// <summary>
/// log
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(MainView));
public readonly MainViewModel mainViewModel;
# endregion
# region Constructor
/// <summary>
/// Default Constuctor
/// </summary>
public MainView()
{
InitializeComponent();
mainViewModel = new MainViewModel();
mainViewModel.Messenger.UnRegister(this);
mainViewModel.Messenger.Register(this);
this.DataContext = mainViewModel;
}
# endregion
# region Protected Methods
/// <summary>
/// LaunchMenuConfigView
/// </summary>
/// <param name="menuConfigViewModel"></param>
[MessengerMessageSink(MessengerMessages.LAUNCH_VIEW_MENU_CONFIG, ParameterType = typeof(MenuConfigViewModel))]
protected void LaunchMenuConfigView(MenuConfigViewModel menuConfigViewModel)
{
log.Debug("LaunchMenuConfigView" + Utility.FUNCTION_ENTERED_LOG);
var menuConfigView = new MenuConfigView()
{
DataContext = menuConfigViewModel,
Owner =GetWindow(this),
};
menuConfigView.ShowDialog();
log.Debug("LaunchMenuConfigView" + Utility.FUNCTION_EXIT_LOG);
}
/// <summary>
/// LaunchNavigationKeyDetailsView
/// </summary>
/// <param name="obj"></param>
[MessengerMessageSink(MessengerMessages.LAUNCH_VIEW_NAVIGATIONKEY, ParameterType = typeof(UtilityViewModel))]
protected void LaunchNavigationKeyDetailsView(UtilityViewModel utilityViewModel)
{
log.Debug("LaunchNavigationKeyDetailsView" + Utility.FUNCTION_ENTERED_LOG);
var navigationScreen = new NavigationKeyDetailsView() {DataContext=utilityViewModel,Owner=GetWindow(this) };
navigationScreen.ShowDialog();
log.Debug("LaunchNavigationKeyDetailsView" + Utility.FUNCTION_EXIT_LOG);
}
/// <summary>
/// ReportProblemMenuItem_Click
/// </summary>
/// <param name="obj"></param>
[MessengerMessageSink(MessengerMessages.LAUNCH_ABOUT_VIEW,ParameterType=typeof(string))]
protected void LaunchABoutView(string obj)
{
log.Debug("LaunchABoutView" + Utility.FUNCTION_ENTERED_LOG);
var aboutScreen = new AboutDialog(Utility.TOOL_NAME,
Utility.TOOL_VERSION);
aboutScreen.ShowDialog();
log.Debug("LaunchABoutView" + Utility.FUNCTION_EXIT_LOG);
}
/// <summary>
/// ReportProblemMenuItem_Click
/// </summary>
/// <param name="obj"></param>
[MessengerMessageSink(MessengerMessages.LAUNCH_REPORT_A_PROBLEM_VIEW, ParameterType = typeof(string))]
protected void LaunchReportProblemView(string obj)
{
log.Debug("LaunchReportProblemView" + Utility.FUNCTION_ENTERED_LOG);
ReportProblemView objReportProblemView = new ReportProblemView
{
Owner = GetWindow(this)
};
objReportProblemView.ShowDialog();
log.Debug("LaunchReportProblemView" + Utility.FUNCTION_EXIT_LOG);
}
/// <summary>
/// FileSelectView
/// </summary>
/// <param name="passwordViewModel">ViewModel Instance of <c>PasswordView</c></param>
[MessengerMessageSink(MessengerMessages.LAUNCH_FILE_SELECT_VIEW,ParameterType=typeof(PasswordViewModel))]
protected void LaunchFileSelectView(PasswordViewModel passwordViewModel)
{
log.Debug("LaunchFileSelectView" + Utility.FUNCTION_ENTERED_LOG);
PasswordView passwordView = new PasswordView
{
DataContext = passwordViewModel,
Owner = GetWindow(this)
};
passwordView.ShowDialog();
log.Debug("LaunchFileSelectView" + Utility.FUNCTION_EXIT_LOG);
}
/// <summary>
/// Launch Ask Password
/// </summary>
/// <param name="changePasswordViewModel"></param>
[MessengerMessageSink(MessengerMessages.ASKFORPASSWORD, ParameterType = typeof(ChangePasswordViewModel))]
protected void LaunchAskPasswordView(ChangePasswordViewModel changePasswordViewModel)
{
log.Debug("LaunchChangePasswordView" + Utility.FUNCTION_ENTERED_LOG);
ChangePasswordView objChangePasswordView = new ChangePasswordView
{
DataContext =
changePasswordViewModel,
Owner = GetWindow(
this)
};
objChangePasswordView.ShowDialog();
log.Debug("LaunchChangePasswordView" + Utility.FUNCTION_EXIT_LOG);
}
/// <summary>
///
/// </summary>
/// <param name="selectionScreenViewModel"></param>
[MessengerMessageSink(MessengerMessages.LAUNCH_SELECTIONSCREEN_VIEW, ParameterType = typeof(SelectionScreenViewModel))]
protected void LaunchSelectionScreen(SelectionScreenViewModel selectionScreenViewModel)
{
SelectionScreenView selectionScreenView =
new SelectionScreenView
{
DataContext =
selectionScreenViewModel,
Owner =
GetWindow(this)
};
selectionScreenView.ShowDialog();
}
# endregion
# region Public Methods
/// <summary>
/// Exit Application
/// </summary>
/// <param name="obj"></param>
[MessengerMessageSink(MessengerMessages.EXIT_APPLICATION,ParameterType=typeof(object))]
public void ExitApplication(object obj)
{
this.Close();
}
#endregion
}
#endregion
Launching Views works otherwise perfect (Like launching through the click of a button) but it doesnot work when i try to launch if while loading ExecutionView.
I am totally stuck .... nothing is working i even tried using dispatcher but still the same error.......
What i am tryinh to do here is When i run my application ExecutionView is loaded in my Main View... in ExecutionViewModel i am Performing some checks to launch another window but i feel that my Execution View is not loaded yet so its giving that problem.... but how to solve it...
Thanks fo the help .... in advance :)
Stack Trace
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Window.ShowHelper(Object booleanBox)
at System.Windows.Window.Show()
at System.Windows.Window.ShowDialog()
at MyMenuTool.ViewLayer.MainView.LaunchFileSelectView(PasswordViewModel passwordViewModel) in C:\AD\MyMenuTool\Code\Working\MyMenu_VS2010\MyMenu\MyMenu\MainView.xaml.cs:line 134
I would like to display an animation gif such as loading... in my XAML as my procedure is progressing. I found out that this cannot be easily done in WPF as I loaded my Gif and it just shows the first frame. What are the best ways to display an animation in WPF.
You can use the following code for loading GIFImage in a WPF app
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
/// <summary>
/// Class to host nornmal and Gif images and plays the animation.
/// To make it work, instead of setting ImageSource, set the AnimationSourcePath property.
/// </summary>
public class GifImage : Image
{
/// <summary>
/// Dependency property to hold value for AnimationSourcePath.
/// </summary>
public static readonly DependencyProperty AnimationSourcePathProperty =
DependencyProperty.Register(
"AnimationSourcePath",
typeof(string),
typeof(GifImage),
new UIPropertyMetadata(String.Empty, AnimationSourcePathPropertyChanged));
/// <summary>
/// Dependency property to hold value of integer animation timeline values for FrameIndex.
/// </summary>
private static readonly DependencyProperty FrameIndexProperty =
DependencyProperty.Register(
"FrameIndex",
typeof(int),
typeof(GifImage),
new UIPropertyMetadata(0, new PropertyChangedCallback(ChangingFrameIndex)));
/// <summary>
/// Dependency property to hold value of integer animation rate which slows down animation speed if value is more than 1.
/// </summary>
private static readonly DependencyProperty FrameRefreshRateProperty =
DependencyProperty.Register(
"FrameRefreshRate",
typeof(int),
typeof(GifImage),
new UIPropertyMetadata(1, AnimationSourcePathPropertyChanged));
/// <summary>
/// Member to hold animation timeline for integer values.
/// </summary>
private Int32Animation anim;
/// <summary>
/// Member to hold flag to indicate if animation is working.
/// </summary>
private bool animationIsWorking = false;
/// <summary>
/// Member to hold Gif Bitmap Decoder.
/// </summary>
private GifBitmapDecoder gf;
/// <summary>
/// Initializes a new instance of the GifImage class.
/// </summary>
public GifImage()
{
}
/// <summary>
/// Initializes a new instance of the GifImage class based on the uri.
/// </summary>
/// <param name="uri">Uri of the image source.</param>
public GifImage(Uri uri)
{
GifImage.SetupAnimationSource(this, uri);
}
/// <summary>
/// Gets or sets a value indicating AnimationSourcePath.
/// </summary>
public string AnimationSourcePath
{
get { return (string)GetValue(AnimationSourcePathProperty); }
set { SetValue(AnimationSourcePathProperty, value); }
}
/// <summary>
/// Gets or sets a value indicating FrameIndex.
/// </summary>
public int FrameIndex
{
get { return (int)GetValue(FrameIndexProperty); }
set { SetValue(FrameIndexProperty, value); }
}
/// <summary>
/// Gets or sets a value for frame refresh rate. A value more than 1 would slow the animation down.
/// </summary>
public int FrameRefreshRate
{
get { return (int)GetValue(FrameRefreshRateProperty); }
set { SetValue(FrameRefreshRateProperty, value); }
}
/// <summary>
/// Method to handle property changed event of AnimationSourcePath property.
/// </summary>
/// <param name="obj">Source image.</param>
/// <param name="ev">Event arguments.</param>
protected static void AnimationSourcePathPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs ev)
{
GifImage ob = obj as GifImage;
ob.BeginAnimation(GifImage.FrameIndexProperty, null);
ob.anim = null;
ob.gf = null;
ob.Source = null;
if (!String.IsNullOrEmpty(ob.AnimationSourcePath) &&
Uri.IsWellFormedUriString(ob.AnimationSourcePath, UriKind.RelativeOrAbsolute))
{
if (((string)ob.AnimationSourcePath).ToLower().EndsWith(".gif"))
{
Uri uri = new Uri(ob.AnimationSourcePath);
GifImage.SetupAnimationSource(ob, uri);
ob.BeginAnimation(GifImage.FrameIndexProperty, ob.anim);
}
else
{
ob.Source = (new ImageSourceConverter()).ConvertFromString(ob.AnimationSourcePath) as ImageSource;
ob.InvalidateVisual();
}
ob.animationIsWorking = true;
}
}
/// <summary>
/// Method to handle property changed event of FrameIndex property.
/// </summary>
/// <param name="obj">Source image.</param>
/// <param name="ev">Event arguments.</param>
protected static void ChangingFrameIndex(DependencyObject obj, DependencyPropertyChangedEventArgs ev)
{
GifImage ob = obj as GifImage;
ob.Source = ob.gf.Frames[ob.FrameIndex];
ob.InvalidateVisual();
}
/// <summary>
/// Method to setup animation source against a Gif Image.
/// </summary>
/// <param name="ob">Gif image.</param>
/// <param name="uri">Uri of the gif image source.</param>
protected static void SetupAnimationSource(GifImage ob, Uri uri)
{
ob.gf = new GifBitmapDecoder(uri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
double val = (ob.gf.Frames.Count / 15.0) - (ob.gf.Frames.Count / 15);
TimeSpan tmpSpn = new TimeSpan(0, 0, 0, ob.gf.Frames.Count / 15, (int)(val * 1000));
Duration durtn = new Duration(new TimeSpan(tmpSpn.Ticks * ob.FrameRefreshRate));
ob.anim = new Int32Animation(0, ob.gf.Frames.Count - 1, durtn);
ob.anim.RepeatBehavior = RepeatBehavior.Forever;
ob.Source = ob.gf.Frames[0];
}
/// <summary>
/// Method to override the OnRender event of the image.
/// </summary>
/// <param name="dc">Drawing Context of the image.</param>
protected override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
if (!this.animationIsWorking)
{
BeginAnimation(GifImage.FrameIndexProperty, this.anim);
this.animationIsWorking = true;
}
}
}
The way you use it as follows....
<ns:GifImage AnimationSourcePath="../MyGifImage.gif" />
Let me know if this helps you.
In current project, i have to create a tab based navigation. Every time we click a module, a new TabControl opens if not alteady created, else focus. To achieve this i use a code like this:
HyperlinkButton link = (sender as HyperlinkButton);
string _name = "TAB_" + link.Name;
TabItem tabItem = (from TabItem item in TabControlID.Items
where item.Name.Equals(_name)
select item).FirstOrDefault();
if (tabItem == null)
{
tabItem = new TabItem();
tabItem.Header = link.Content;
tabItem.Name = _name;
tabItem.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
tabItem.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
switch (link.Name.ToString().ToLower())
{
case "taclass":
taClass_List taclass_list = new taClass_List();
tabItem.Content = taclass_list;
break;
}
TabControlID.Items.Add(tabItem);
tabItem.UpdateLayout();
TabControlID.UpdateLayout();
}
TabControlID.SelectedItem = tabItem;
This is working as expected, every tab has a UserControl associated (taClass_List in sample) where a grid with data is displayed. I have a few buttons to manage data: Add new record, Export to excel, Print data, Edit record and Delete record. The code for taClass_List is this
public partial class taClass_List : UserControl
{
private CespDomainContext _context = new CespDomainContext();
/// <summary>
///
/// </summary>
public taClass_List()
{
InitializeComponent();
LoadOperation<ta_Class> loadOp = this._context.Load(this._context.GetTa_ClassQuery());
MainGrid.ItemsSource = loadOp.Entities;
MainPager.Source = loadOp.Entities;
}
/// <summary>
/// s
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void saveChanges()
{
_context.SubmitChanges(OnSubmitCompleted, null);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rejectChanges()
{
_context.RejectChanges();
CheckChanges();
}
/// <summary>
///
/// </summary>
private void CheckChanges()
{
EntityChangeSet changeSet = _context.EntityContainer.GetChanges();
bool hasChanges = _context.HasChanges;
}
/// <summary>
///
/// </summary>
/// <param name="so"></param>
private void OnSubmitCompleted(SubmitOperation so)
{
if (so.HasError)
{
MessageBox.Show(string.Format("Submit Failed: {0}", so.Error.Message));
so.MarkErrorAsHandled();
}
CheckChanges();
}
(...)
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btAdd_Click(object sender, RoutedEventArgs e)
{
taClass_Form objform = new taClass_Form();
objform.IsTabStop = true;
objform.IsHitTestVisible = true;
objform.DataContext = _context;
objform.UpdateLayout();
objform.Closed += new EventHandler(objform_Closed);
objform.Show();
//MainPage.showWindow(objform);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void objform_Closed(object sender, EventArgs e)
{
taClass_Form objform = (taClass_Form)sender;
if (objform.MainObject != null)
{
//MainDataSource.DataView.Add(objform.MainObject);
//MainDataSource.SubmitChanges();
}
objform = null;
}
}
When i click Add New record button, btAdd_Click function is called, Childwindow appears but i receive an error message
Invalid attribute value for property Visibility
at MS.Internal.XcpImports.VisualStateManager_GoToState(Control reference, String StateName, Boolean useTransitions, Boolean& refreshInheritanceContext)
at System.Windows.VisualStateManager.GoToState(Control control, String stateName, Boolean useTransitions)
at System.Windows.Controls.ValidationSummary.UpdateCommonState(Boolean useTransitions)
at System.Windows.Controls.ValidationSummary.ValidationSummary_IsEnabledChanged(Object sender, DependencyPropertyChangedEventArgs e)
at System.Windows.Controls.Control.OnIsEnabledChanged(Control control, EventArgs args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
taClass_Form code is (so far):
public partial class taClass_Form : ChildWindow
{
public ta_Class MainObject = null;
public taClass_Form()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
}
What am i doing wrong? Please help me
Thanks in advance.
After some more research, i discovered that problem is related with SilverLight Toolkit Themes.
I disabled theming in project and no more errors.
Thanks