All of us who have been designing and developing using XAML technologies use ICommand interface on a daily basis. The interface requires implementation of Execute() and CanExecute() methods. Here Execute method is used to perform an action in response to a user interaction. However, the action can only be executed if CanExecute() method returns true. You might have commonly seen a Command being bound to a button. In this case, button would be enabled or disabled based on the evaluation of CanExecute() method of the ICommand. Now let me throw the main question in the air...
Can we run into a situation when a button is enabled when it is not supposed to, and How often ICommand.CanExecute() is called?
Let me first give you the answer of first part of the question, YES, we can certainly run into situations when a button should be disabled when it is supposed to be enabled and vice versa.
The second part of the question is tricky. It is dependent upon the implementation of ICommand. Other than the required Execute and CanExecute() methods, the interface also requires implementation of CanExecuteChanged event. So CanExecute method would be called in all those instances when the command raises this event. If you look at Josh Smith's implementation of ICommand i.e. RelayCommand, here we are directly hooking it up with CommandManager.RequerySuggested event. Now all user interactions would result in re-evaluation of CanExecute(). But what if the underlying property changes value in response to an event other than any user action. In all those situations, we could face this problem.
We might have different implementations handling this differently. This is quite similarly handler in MVVMLight Libs.
And this is from Prism's DelegateCommand type. That's why we need to call RaiseCanExecuteChanged for DelegateCommand every time we need re-evaluation of CanExecute method.
In order to understand the severity of the problem, let's create a sample WPF application. The following is a sample view model with FirstName property of type string. It also has an ICommand property, SubmitCommand. Here we are using Josh Smith's implementation of ICommand i.e. RelayCommand. The code can be found at his original article on msdn. In the command's CanExecute() method, we are checking if FirstName is null or empty, we are returning false in this case. This should disable the button.
And here is the view which is using the view model, defined above, as its DataContext. It is Binding the FirstName property to a TextBox. Since UpdateSourceTrigger is set as PropertyChanged, it would continue to update the source property as user keeps modifying the text. It also has a button which binds its Command property to view model's SubmitCommand. Now clicking the button should cause running the Execute method of the command. The button should be enabled only when the command's CanExecute() method returns true.
As we are modifying the text in the TextBox, we see that as we empty the TextBox, the button is disabled, which is as expected.
Actually modifying the content of the TextBox cause CommandManager.RequerySuggested to be triggered. Since RelayCommand uses this, it causes CanExecuteChanged event to be triggered. Since the UI framework hooks up to this event. It causes CanExecute to be called.
In order to understand the problem, let's add the following code to our view model. It just flips the value of FirstName property between string.Empty and "Not Empty" literal. Here we expect that as soon as we set it to String.Empty, the button should be disabled. Here we are using a System.Timers.Timer for this purpose. Since Elapsed event is invoked on a ThreadPool thread, the value is being updated without any user interaction on a non-UI thread. Since WPF is very forgiving about PropertyChanged on a non-UI thread, we don't have Dispatcher issues for assigning a value to FirstName in this thread.
Let's run the application and see the result. As shown here, the button is always enabled. This is how we have defined CanExecuteChanged event in RelayCommand. Since MVVMLight's RelayCommand is also defined similarly, we should have the same problem there. For Prism's DelegateCommand, we need to call RaiseCanExecuteChanged(), which raises CanExecuteChanged event for the command.
Now we understand the problem. In the next post, we are going to see how we can resolve it. Stay tuned!
Tuesday, April 8, 2014
Reactive UI - Part I [ Setting the Ground Up ]
Tuesday, April 1, 2014
Viewing Markdown Text in WPF Applications
From HTML to XML, we have seen a lot of markup languages. They are generally considered as languages which have TAGS. These tags are generally angle brackets. Historically, the word came from book publishing. If you look at Wikipedia, Markup languages are defined as follows:
A (document) markup language is a modern system for annotating a document in a way that is syntactically distinguishable from the text.
So it is to provide extra information with the text in order to further define it. These annotations can be used for presentation and processing of the text. It can also set some piece of text aside from such treatment. Generally, the presentational aspect of markup are considered and used. These languages describe how some data should be formatted and displayed. They are document formatting in nature. Since we have different data display requirements in various scenarios, there are many markup languages developed to handle them. HTML describes formatting of documents displayed in a browser. So it is browser specific and cannot be used outside its context.
The idea of Markdown is considered an opposite of Markups. This was created by John Gruber in 2004. For Markdown, we describe how data should be presented, but this is not specific to any target engine. You can develop a parser to render the input text to your required format. As the world is getting older, we have more and more need to support cross platform applications as developers. So, we can write some text in a Markdown style and transform it to the format of our choice. The concept is similar to Rich Text Format (RTF) but this is not properietry. There are a number of markdown flavors but we are not going to discuss them here as they still need to be standardized.
The standard file extension of a markdown file is *.md. As Markdown has gained popularity, it has enjoyed very fast industry wide acceptance. The most popular amongst the adopters of the format is StackOverflow.com. Wordpress and other Blog Engines have plugins to support the format. Even GitHub's Read Me file uses this format. Vim , Notepad++ and Sublime editors also have plugins to support Markdown syntax highlighting and previewing.
Markdown Editors
There are many markdown editors available. They are available online and for installation. I am listing some of them here. Just search for Markdown Editors.
Let's write some Markdown now!
Let's write some markup now. Here we are using Markdown.Xaml tool. The tool can be downloaded from here.
You can download the markdown text from the following. It is in markdown format. Since we have saved it using *.md file extension, it is displayed as formatted. Just select View Raw from the following editor.
Let's see how easy it is to convert the Text to Html. We can use MarkdownSharp nuget pacakge for this purpose for our .net applications. It provides the type to transform a markdown text. The tool supports transformation to HTML format.
Let's see how the converted text looks like. Here we are previewing the converted text in Text Visualizer in Visual Studio.
How to use this for WPF?
Since this is giving output as HTML, the easiest option is to use a browser control and somehow render this converted HTML as browser already supports such formatting. What if we don't or can't use it like that. Is there a way to show it as native WPF. Yes, there is. But we need to use a solution from Bevan Arps. There is currently no nuget package for this. But since the code is available on GitHub, we can get the code and build it locally. We can the use the library and reference it in our project.
Running the code would read the markdown text from the file. It then transforms it using the Markdown type. The type transforms the text into FlowDocument, which can directly be used in a WPF application. As you can notice, the utility is not perfect as you can notice that Heading has not been transformed correctly. But this can be good enough for your needs. Just check it out!
This solution should be good for WPF. Silverlight doesn't support FlowDocument yet. So you might want to search for other solutions for markdown. Although you should be able to find some Markdown editors in Windows Phone and Silverlight, but I couldn't find a Markdown viewer for them.
A (document) markup language is a modern system for annotating a document in a way that is syntactically distinguishable from the text.
So it is to provide extra information with the text in order to further define it. These annotations can be used for presentation and processing of the text. It can also set some piece of text aside from such treatment. Generally, the presentational aspect of markup are considered and used. These languages describe how some data should be formatted and displayed. They are document formatting in nature. Since we have different data display requirements in various scenarios, there are many markup languages developed to handle them. HTML describes formatting of documents displayed in a browser. So it is browser specific and cannot be used outside its context.
The idea of Markdown is considered an opposite of Markups. This was created by John Gruber in 2004. For Markdown, we describe how data should be presented, but this is not specific to any target engine. You can develop a parser to render the input text to your required format. As the world is getting older, we have more and more need to support cross platform applications as developers. So, we can write some text in a Markdown style and transform it to the format of our choice. The concept is similar to Rich Text Format (RTF) but this is not properietry. There are a number of markdown flavors but we are not going to discuss them here as they still need to be standardized.
The standard file extension of a markdown file is *.md. As Markdown has gained popularity, it has enjoyed very fast industry wide acceptance. The most popular amongst the adopters of the format is StackOverflow.com. Wordpress and other Blog Engines have plugins to support the format. Even GitHub's Read Me file uses this format. Vim , Notepad++ and Sublime editors also have plugins to support Markdown syntax highlighting and previewing.
Markdown Editors
There are many markdown editors available. They are available online and for installation. I am listing some of them here. Just search for Markdown Editors.
Let's write some Markdown now!
Let's write some markup now. Here we are using Markdown.Xaml tool. The tool can be downloaded from here.
You can download the markdown text from the following. It is in markdown format. Since we have saved it using *.md file extension, it is displayed as formatted. Just select View Raw from the following editor.
Let's see how easy it is to convert the Text to Html. We can use MarkdownSharp nuget pacakge for this purpose for our .net applications. It provides the type to transform a markdown text. The tool supports transformation to HTML format.
Let's see how the converted text looks like. Here we are previewing the converted text in Text Visualizer in Visual Studio.
How to use this for WPF?
Since this is giving output as HTML, the easiest option is to use a browser control and somehow render this converted HTML as browser already supports such formatting. What if we don't or can't use it like that. Is there a way to show it as native WPF. Yes, there is. But we need to use a solution from Bevan Arps. There is currently no nuget package for this. But since the code is available on GitHub, we can get the code and build it locally. We can the use the library and reference it in our project.
Running the code would read the markdown text from the file. It then transforms it using the Markdown type. The type transforms the text into FlowDocument, which can directly be used in a WPF application. As you can notice, the utility is not perfect as you can notice that Heading has not been transformed correctly. But this can be good enough for your needs. Just check it out!
This solution should be good for WPF. Silverlight doesn't support FlowDocument yet. So you might want to search for other solutions for markdown. Although you should be able to find some Markdown editors in Windows Phone and Silverlight, but I couldn't find a Markdown viewer for them.
Subscribe to:
Posts (Atom)