How to get command line args in WPF?

Are you looking how to get the command line arguments in WPF?

It is actually really easy. Simple call Environment.GetCommandLineArgs()

You will be returned a string array (string[]). Remember, the first value is that of the exe being called. i.e your app.

 

[csharp] Environment.GetCommandLineArgs() [/csharp]

Happy Coding!

How to handle keypress in WPF using MVVM?

Did you want to capture the Enter key on a textbox, or the F3 key for find again in your WPF Application when you are using MVVM?

I was using custom behaviors for a while until I realized I was overcomplicating things far too much.

You can wire up commands right to keys very easily.

Here is a sample. Same concept for any framework control.

[sourcecode language=”csharp”]
<Window.InputBindings>
<KeyBinding Command="{Binding FindNextCommand}" Key="F3"/>
</Window.InputBindings>
[/sourcecode]

If you had a textbox, just set the TextBox.InputBindings and the key to Enter. Happy Coding!

How do I bring to front a WPF Window?

If you are a WinForms, Visual Basic, or basically a programmer from a past generation, then you are wondering where the heck the BringToFront method is. Yes, we could invoke API’s on the window handle (that was the norm when I started programming Windows, DOS was so much easier). Anyway, WPF likes to do things with highly unobvious naming.

So, if you want your WPF window to come to the front, apparently you now Activate it. Yup. I preferred the BringToFront way more.

Anyway, Activate works fine.

var window = new YourWindowClass();

window.Show();

……

//Sometime later it is behind your main app for whatever reason, user put it there, but you now you want it in front.

window.Activate();

 

My use is I have a singleton window that gets shown and hidden, but if it is shown and not in front, I want it brought to front so the user doesn’t get confused.

Simple function, been since Windows could overlay, but in WPF you get a new methodology for invoking it.

 

Happy coding!

Death by icon: Memory Leak in WPF Using MVVM and ImageSource

I was running a memory profile on our client application and kept seeing views being stuck in memory. It was odd since we freed them and there weren’t any discernable links that should be keeping them alive.

Well, that is until I saw that a GC Root object holding a reference at the top of the chain was an icon. An Icon. It was holding together a massive view and all the data, controls and containers that go with it. The memory would increase by 5-10 megs each time you went and left the view.

So, my next step was to figure out how in the world this icon was holding the view in memory. Where was the reference? The only usage was a simple binding to show the icon for particular types of nodes in our treeview.

I remembered from an earlier performance run that WPF has Freezable objects. WPF monitors these objects for changes. Well, that sounds like it uses an event. I doubt it polls.

I was right. There is an event on the image source. Apparently WPF latches on to that bad boy, and voila. You have a valid reference to the icon that the GC see as needed.

Why needed, well, to save cycles, we use a static instantiation of the bitmap. Loading from resources is expensive, so we use a readonly static. It never goes anywhere, therefore anything bound to its events doesn’t go anywhere.

So, what is the fix? I don’t want to stop using my static, as now I introduce a performance penalty. I can’t stop using the icon, then the user would be perturbed.

What to do?

Well, bring out your ice ray gun, because the solution is to Freeze the image. I mentioned earlier that WPF has Freezable objects. Well, if you Freeze it, then WPF doesn’t bind to the event since the object can’t change. So, a few lines of code later and we have a memory leak disaster averted.

Here was the old way:

[csharp]
private static readonly ImageSource MyIcon = new BitmapImage(new Uri("pack://application:,,,/Seekford.Client.Resources;component/Images/Icon.png")); 
[/csharp]

Here is the new way:

[csharp]
   private static readonly ImageSource MyIcon;
        static MyTreeModel()
        {
            MyIcon = new BitmapImage(new Uri("pack://application:,,,/Seekford.Client.Resources;component/Images/Icon.png"));        
            PARRiskIcon.Freeze();           
        }
[/csharp]

Simple, right. Yeah, if you know what to look for in the first place Smile

 

Happy coding!

WPF IValueConverter Culture isn’t what you expect

I came across a defect that our DateTime IValueConverter wasn’t showing the local users regional settings.

I set a breakpoint into the converter and looked at the culture variable being passed in. The ShortDateFormat was "M/d/yyyy".

Well, my regional was set to "dd-MMMM-yy"

What gives?

I checked CultureInfo.CurrentUICulture. It had the right format string.

I attempted the language override fix:

[csharp]
  //Defaulting WPF to use at least the current cultures default values. Converters will still not use the local UI culture by default...
                FrameworkElement.LanguageProperty.OverrideMetadata(
                        typeof(FrameworkElement),
                        new FrameworkPropertyMetadata(
                        System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentUICulture.IetfLanguageTag)));
[/csharp]

Didn’t help with my scenario at all.

So, in the end, I just used CultureInfo.CurrentUICulture to format the string. A bit annoying.

[csharp]
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null) return NoDateString;
            var d = value as DateTime?;

            if (d.HasValue) return d.Value.ToString(parameter.ToString(),System.Globalization.CultureInfo.CurrentUICulture);
            return value.ToString();
        }
[/csharp]

If you find a better way, please feel to drop me a note.

Happy coding!

Perforator doesn’t allow me to attach to any processes

Are you using the WPF Perforator in the WPF Performance suite and wondering why the process attach dialog has everything greyed out and disabled?

So did I. It drove me nuts, until I found out one key thing. Apparently, Perforator can only attach to processes that were started AFTER the Perforator tool was.

Gee…Wouldn’t that have been a nice thing to show in the dialog as a hint? Apparently, no one writing that tool thought about the UX in that scenario. Showing them greyed out, brilliant.  A tooltip, message, anything that said "This process can not be attached to because it was started before Perforator" would have saved serious time.

Hopefully this little nugget will save you time as well.

So, how do you attach Perforator to a running process? Start Perforator first,start your process next, then attach. Simple, yes. Intuitive, no.

Of course, you are coding in WPF. Did you expect anything to make sense?

Happy Coding!

How do I cancel a databinding property set in WPF?

I have a combobox in WPF that I am using the SelectedItem property with a DataBinding and sometimes certain items shouldn’t be selected based on certain criteria. Mine was that two comboboxes couldn’t have the same value.

Yes, there are other ways, such as removing invalid values from other boxes, but here was my solution for preventing the invalid property set by cancelling the selection/property set.

WPF sucks in this manner as there isn’t an easy way to update it. You can’t raise the property updated event since the binding ignores those when setting, to avoid recursion issue I suppose. (Yes, developers could defend by not raising the events if the property doesn’t change)

Anyway, the solution is simply to raise the property changed after the operation, by simply posting it to the work queue on the UI thread right afterward.

 

Code: in C#

public MyHeaderType SelectedHeader
      {
          get { return this.selectedHeader; }
          set
          {
              bool resetMe= validateValue(value);
              var origVal = selectedHeader;//store for reset

              selectedHeader = value;
              RaisePropertyChanged(() => SelectedHeader);

              if (resetMe)//Why do I need to set the value above? No idea. Doesn’t work unless I do it that way. Yes. I tried.
              {
                  Application.Current.Dispatcher.BeginInvoke( //force a reenter to put it back……
                                new Action(() =>
                                {
                                    SelectedHeader = origVal;//put me back to the correct value.
                                }),
                                DispatcherPriority.ContextIdle,
                                null
                            );                           
              }
          }
      }

 

 

 

Happy Coding!

How to set the BackgroundColor on a GridViewColumn in WPF!

So, you figured you would set the Grid or Border background color and it would work out? Then you ran your program and only the text was being filled in with your color right?

Well, the issue is two fold. First, you need to set the cell contents to stretch. Then you need to get past the fact the column pads the cell by 6 pixels left and right.

Handling the padding is here:

<Style TargetType="Border" x:Key="columnBorder">
                                <Setter Property="Margin" Value="-6,-2,-6,-6"/>
                                <Setter Property="Padding" Value="6,2,6,6"/>

</Style>

 

 

Set the HorizontalContentAlignment on the ListView or GridView.

Hope this helps.

I googled around for other entries and found this one with more detail than I wanted to write.

http://www.interact-sw.co.uk/iangblog/2007/05/30/wpf-listview-column-margins

Happy coding!