Thursday, February 19, 2009

Pandora WTF

I was sitting here jamming out to some Pandora this morning, and wondered what song I was hearing, so I flipped over to my desktop to see what was playing and I see this:

PandoraPanteraWTF

That’s the cover for Pantera’s Reinventing the Steel album??

Tuesday, February 10, 2009

Responsive WPF Interfaces

I had a bit of a challenge today while trying to get a WPF ProgressBar to send feedback to my UI while a long-running processes ran. 

My first challenge was finding “that one property that lets the ProgressBar animation run continuously” – IsIndeterminate. 

My next challenge was setting the IsIndeterminate property to true before firing off my long-running process.   I remembered something about using the Dispatcher, but even using that didn’t reflect the ProgressBar property changes to the UI.  I briefly considered trying an evil DoEvents type trick, but came to my senses before heading down that road.

I landed on creating a delegate which I could invoke to fire off my long-running process, and it ended up looking something like this (forgive the crude method names, this was some spike code I was playing around with:

private delegate void UpdateProgressbarIndeterminateState(bool isEnabled);
private void CompareClick(object sender, RoutedEventArgs e){
Dispatcher.Invoke(DispatcherPriority.Normal,
(UpdateProgressbarIndeterminateState)
delegate(bool isIndeterminate){
progressBar.IsIndeterminate = isIndeterminate;
}, true);

AsyncDelegate caller = PerformCompare;
caller.BeginInvoke(AfterCompareCallback, null);
}

internal delegate void AsyncDelegate();
private static void PerformCompare() {
DataComparer.Execute();
}

protected void AfterCompareCallback(IAsyncResult ar) {
Dispatcher.Invoke(DispatcherPriority.Normal,
(UpdateProgressbarIndeterminateState)
delegate(bool isIndeterminate) {
progressBar.IsIndeterminate = isIndeterminate;
}, false);
}

Tuesday, February 03, 2009

WPF DataGrid Conditional Formatting

I recently ran into a problem on my project where I needed to apply some conditional formatting to WPF DataGrid Cells based upon values from another property in my bound object.

The requirement was pretty simple: if condition is met, change the cell-text color to red, otherwise, leave it black.  What should have been a pretty simple task (never heard a programmer say that, right?) ended up taking me more time than I’d care to admit.

After fumbling around with a few attempts at the IValueConverter and a DataTemplateSelector, I still was not having any luck in getting my conditional formatting to work.  I eventually landed back at my usual source of information for the WPF Toolkit – CodePlex, and “shockingly”, the answer was in the discussion for the project.

I had been fighting the “Foreground” property of the DataGridTextColumn directly, trying what was recommended in this article, but I just couldn’t get that working.  Once I followed the CodePlex forum recommendation of embedding a CellStyle into the DataGridTextColumn, things worked as expected.

Friday, January 30, 2009

Two-way Data Binding with WPF DataGrids

We’re making use of the the WPF Toolkit’s DataGrid control in my current project and have solved a few things along the way that weren’t entirely obvious to us at the start. One of these things was figuring out how to automatically reflect domain object changes in the UI.

Of the three developers on this project, Nik Clarkson has the most background with WPF and we usually throw out ideas to him and he “translates” what we want to do to into WPF terms and we’re off and running. In the case of getting our UI to reflect domain model changes, he mentioned BindingMode.

I was able to find some examples that showed how to do this in XAML pretty quickly, but I spent a few cycles trying to get this to work with a DataGridColumn that I was adding programmatically. My first attempt looked like how you’d do it in XAML a-la new Binding("Price, Mode = BindingMode.Two-way”), but that didn’t work.

I decided to make up a fresh batch of coffee in the team french-press, and then it hit me: object initializers. A quick edit and I ended up with following:

var priceColumn = new DataGridTextColumn{ Header = "Price", Width = DataGridLength.Auto,
Binding = new Binding("Price") { Mode = BindingMode.Two-way, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }};
ResultsGrid.Columns.Add(priceColumn);
This worked perfectly with the “Price” property I was binding to, since this was a property on one of our LINQ to SQL objects, and as such was raising the property-changed event for us in the generated code. When I went to do the same thing with another column (one not generated by the LINQ to SQL designer), I wasn’t seeing my edits reflected in my UI, but did see them in the domain objects via the debugger.

I had forgotten to raise the property-changed event in my ProposedPrice setter, so once I changed it to the following, everything worked great.
if (_proposedPrice != value)
{
SendPropertyChanging();
_proposedPrice = value;
SendPropertyChanged("ProposedPrice");
}

Wednesday, January 28, 2009

I just discovered something

One Kashi honey/cinnamon oatmeal packet plus a scoop of chocolate Muscle Milk with a bit of water and milk makes for one tasty breakfast/snack.

That is all.