Posts Tagged WPF
The PropertyChangedCallback on a DependecyProperty is never called on NotifyPropertyChangedEvents for certain properties
Posted by Morten in Uncategorized on July 11, 2011
The user interface of RemoteX Applications has a concept of linking objects to each other. This is described in the UI very similar to a link on a webpage. Some of these links can be changed using an autocomplete like scenario.![]()
These links have had us create user controls to handle them. We’re doing some changes to the interaction to these controls as such we had an issue where the controls never updated their content. This was due to the PropertyChangedCallback was never fired on their dependency property.
The backing field for a link looks something similar to this:
public IRef Contract { get { return _contract; } set { _contract.Href = value.Href UpdateContract(); OnPropertyChanged( Properties.Contract ); } }
As you can see the actual object is never changed, we just change the link on the object.
Apparently WPF optimizes its bindings using ReferenceEquals. The PropertyChangedCallback event is never fired if the bound property is still bound to the same object. so the user control never gets the changed object. This can cause problems for other scenarios as well.
The solution for us was to always return a new copy of the link. That way the user control’s PropertyChangedCallback is always fired. Example below:
public IRef Contract { get { //We need to return a new instance of an IRef here since WPF does ReferenceEquals to check for changes return new Ref<IContract>(_contract); } set { _contract.Href = value.Href UpdateContract(); OnPropertyChanged( Properties.Contract ); } }
Bananas!
Posted by Morten in Uncategorized on November 15, 2010
During Android Only Erik Hellman from Sony Ericsson explained how they create their Android Phones.
During his talk he mentioned that they put all phones through a monkey test. Where a phone has to sit for days with random input on the phone, without crashing.
Naturally the thought is, I wondered how the applications I’m working on would stand against such a test. A monkey test should find all places where the input validation fails, and thus crash.
So I started searching around for tools that did this for Windows Applications. However All I could find was the Hopper Windows Mobile stress test tool, and nothing for desktop Windows Applications.
The thought is if I should write my own, focusing on .Net desktop applications. A tool that sends keystroke and mouse move messages to an application generating random user input. The tool could constrain only to use certain keys or prevent certain patterns from occurring. It could restart the application when it crashes, and log all crashes to a log-file.
It could be quite easy to create a command-line interface for it and execute it in a build system. Naturally a good name for a monkey testing tool would be “Bananas!”
So far it’s just an idea.
MSBuild fails to compile WPF with: error MC2000: Unkown build error ‘…’ does not have an implementation
Posted by Morten in Uncategorized on June 14, 2010
My initial solution in this post was WRONG, it just changed the compile order of our build which made the error occur later after other issues were resolved. I’ve updated the post accordingly. I’m sorry if anyone had to read this post twice.
We have been struggling with a build error lately, where the compilation works perfectly in Visual Studio, and in our case it also works in some MSBuild builds but not in this specific build. By that I mean that two builds are compiling the same code, with the same dependencies and compilation flags, yet one fails and the other doesn’t.
The error message given is:
D:\Invoicing\UQList.xaml(55,167): error MC2000: Unknown build error, 'Method 'add_PropertyChanged' in type 'UsageQuantityPresenter' from assembly 'ServiceManagementApplication' does not have an implementation. Line 55 Position 167.'
If we look at the buildlog.txt produced by MSBuild in the failing build, we can find something similar to this:
Input file 'D:\Invoicing\UQList.xaml' is resolved to new relative path 'Invoicing\UQList.xaml' at directory 'D:\'. D:\Invoicing\UQList.xaml(55,167): error MC2000: Unknown build error, 'Method 'add_PropertyChanged' in type 'UsageQuantityPresenter' from assembly 'ServiceManagementApplication' does not have an implementation. Line 55 Position 167.' Input file 'D:\Trait\TraitsView.xaml' is resolved to new relative path 'Trait\TraitsView.xaml' at directory 'D:\'. ... Generated BAML file: 'D:\obj\Release\Themes\luna.normalcolor.baml'. Generated BAML file: 'D:\obj\Release\Trait\TraitsView.baml'. Markup compilation is done. Done executing task "MarkupCompilePass2" -- FAILED. Done building target "MarkupCompilePass2" in project "ServiceMangementApplication.csproj" -- FAILED.
In the XAML we are depending on the UsageQuantityPresenter to implement INotifyPropertyChanged, which it does. However it also implements other interfaces and does inheritance of a base-class.
This is what it looked for for us:
/// <summary> /// UsageQuantityPresenter /// </summary> public class UsageQuantityPresenter : EntityViewPresenterBase, IUsageQuantity { ...
The EntityViewPresenterBase (I hate that class name by the way) implements INotifyPropertyChanged.
The solution was found in the following forum tread: http://social.msdn.microsoft.com/Forums/en/wpf/thread/00907c94-c6b2-4bf1-98f9-113c5c4392d8
It states that you should add:
<AlwaysCompileMarkupFilesInSeparateDomain>true</AlwaysCompileMarkupFilesInSeparateDomain>
to the .csproj file with the XAML files. Doing this makes MSBuild happy again.
WPF Command execution and click event execution on buttons
Posted by Morten in Uncategorized on August 18, 2009
I had to fix a bug today that was caused by the order of which a command and a click event was executed on a WPF button. I found no documentation of it so I thought I’d make a note of it.
If you have a WPF button like so:
<Button Command="{Binding Clear}" Click="ClearClicked" "></Button>
Then the click event gets executed first and the command is executed after.
Thus you can have the command as a separation layer between the ui and the presentation model. Having the command make the changes on the presentation layer, and have the click event handler to handle how the UI reacts to pressing the button.
If you for some reason need to have the UI execute after the command is executed, then I suggest a command class like the following:
using System;
/// <summary>
/// An ObservableCommand is a command where the execution of the command can be monitoried and thus acted upon;
/// </summary>
public abstract class ObservableCommand : ICommand
{
///<summary>
/// The event fired when a command is executed;
///</summary>
public event EventHandler CommandExecuted = delegate { };
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.
/// </param>
public void Execute( object parameter )
{
ExecuteCommand( parameter );
CommandExecuted(this, EventArgs.Empty);
}
protected abstract void ExecuteCommand( object parameter );
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.
/// </param>
public virtual bool CanExecute( object parameter )
{
return true;
}
protected void RaiseCanExecuteChanged()
{
CanExecuteChanged( this, EventArgs.Empty );
}
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged = delegate { };
}
So how to use this class?
First of, make sure your command class inherits from it like so:
////// The save command /// internal class SaveCommand : ObservableCommand
Then hook on the CommandExecuted event to do your UI action accordingly:
Save.CommandExecuted += Save;
...
void Save( object sender, EventArgs e1 )
{
_textBox.AddText(string.Empty);
_textBox.Focus();
}
To use this command in WPF is just like using any other command.
<button command="{Binding Save}" ...>
Left aligning wpf grid headers
Posted by Morten in Uncategorized on March 25, 2009
Applying this style to the gridviewcolumns they will left align their header content.
<Style x:Key=”LeftAlignedGridHeader” TargetType=”{x:Type GridViewColumnHeader}”>
<Setter Property=”HorizontalContentAlignment” Value=”Left” />
</Style>