Best wpf questions in August 2010

WPF: Handle editable hierarchical data / TreeView~DataGrid hybrid

14 votes

I am looking for a WPF control which is a hybrid of TreeView and DataGrid, something like the Visual Studio debugger or QuickBooks contacts list etc.

Any other solution on how to handle editable hierarchical data in WPF will be very welcommed as well.

alt text

just have a look at this control

http://www.codeproject.com/KB/WPF/wpf_treelistview_control.aspx

Brushed steel brush in WPF?

9 votes

I am looking for ideas to create a WPF Brush with a brushed steel look, similar to the MacOSX Panther style, preferably without resorting to an ImageBrush. Is there a funky way to use a GradientBrush to create this effect?

Thanks in advance!

I don't know how to do this easily with programmatic brushes, but when I have used Photoshop to create a brushed steel effect, I essentially created noise, then smeared (blurred) it in the direction of the brushing:

http://www.adamdorman.com/tutorials/brushed_steel_tutorial.php

As someone mentioned in comments, you may want to do this, and create some sort of (repeating?) image brush. If you want your brushed steel effect to be programmatically generated, you could write a mean filter to do the blur for you. Generating noise is simple enough :)

An example of implementing a mean filter:

http://homepages.inf.ed.ac.uk/rbf/HIPR2/mean.htm

Modify this to have a Nx1 matrix, or have small (zero) for weights not on the current line, and you will have a horizontal blur.

Inconsistent anti-aliasing in WPF 3.5

8 votes

I am getting strange aliasing behaviour in a WPF app using FluidKit's ElementFlow control. We are using the control in an app at work for presenting content, and when the elements of the ElementFlow are tilted, the edges alias as per the following image: Aliased edges

In order to avoid the aliasing, we decided to get rid of the tilt angle, so I created a quick test app where I bound the tilt angle, item gaps, and popout distance to sliders so I could find out what looked best.

However, in the test app using the same settings, the edges are nicely anti-aliased: Anti-aliased edges

I am assuming there is some setting somewhere up the XAML hierarchy that is controlling this but I've tried setting SnapsToDevicePixels on various elements and styles, both at design time and run time (with bindings and tools like Snoop) to no avail.

The XAML for the ElementFlow is as follows:

<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <Fluid:ElementFlow
            x:Name="ContentElementFlow"
            SelectedIndex="{Binding SelectedIndex}"
            Focusable="True"
            TiltAngle="15.95"
            ItemGap="0.722"
            FrontItemGap="0.052"
            PopoutDistance="1.631"
            HasReflection="False"
            Background="Transparent"
            CurrentView="{StaticResource CoverFlowView}"
            ElementWidth="175"
            ElementHeight="250"
            >
            <Fluid:ElementFlow.Camera>
                <PerspectiveCamera
                    FieldOfView="60"
                    Position="0,0,6"
                    LookDirection="0,0,-6"
                    UpDirection="0,1,0"
                    />
            </Fluid:ElementFlow.Camera>
        </Fluid:ElementFlow>
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

I've also tried both apps on two different machines (one running XP Pro, one XP Embedded, both have differing levels of dedicated graphics) and both demonstrate aliasing in one app and anti-aliasing in the other.

Does anyone know of any setting or XAML attribute that can be used to control this?

If I remember correctly there is a bug in WPF 3.5 regarding aliasing in this scenario, I can't for the life of me find the relevant information, but from what I remember it was a Direct X flag that was not being set correctly by WPF.

I remember finding that if you wrap the offending element in certain types of parent elements it seemed to fix the problem. For instance I think wrapping the offending element in an empty border fixes the problem? Again, I can't for the life of me find the information again, but if I find it I will update my answer.

I assume the differences you are seeing between applications are related to this. In the app that show aliasing are the items in the ItemTemplate wrapped in some sort of parent element (where as the test app they are not)? Or vice-a-versa?

Sorry I can't be of more help, still looking for the information but my Google powers seem weak today.

UPDATE: Ok I found what I was thinking of.

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7382637b-b4bc-4a46-8bed-f36250a65385/

This was related to effects so maybe this isn't the same thing you are seeing but worth a shot.

How well is WPF being adopted?

7 votes

I love programming in WPF and .NET in general. It's extremely powerful, flexible, and you can do cool stuff in it.

But I'm a little worried about whether it's getting much traction. When I talk to other sw engineers people don't seem to know much about it and the WPF sections on lots of online developer forums tend to get very light traffic.

2 years ago someone here (http://stackoverflow.com/questions/37944/how-popular-is-wpf-as-a-technology) posted a question about this, so I want to revisit this now in 2010.

Does WPF have legs? Is it really going to take off? Does it have major corporate adopters? Since I enjoy programming with it is it a good career move for the next few years?

Thanks in advance for any comments or opinions!

For what it's worth, right now StackOverflow shows 9,000 WinForms tags and 15,000 WPF tags -- hardly light traffic.

That could just mean people have more difficulty with it, but IMO the momentum has been shifting. I don't personally know anyone starting new greenfield projects in WinForms anymore.

Are the engineers to whom you are talking already working in the .NET stack? If they don't know about WPF it probably just means they work somewhere that is not creating new desktop applications. They could be maintaining existing applications or working in the web space, in which case they'd have little incentive outside of pure curiosity for exploring the current state of Windows Client technologies.

Also IMO, it is good from a career perspective, because it is so highly (and ever-increasingly) overlapped with Silverlight. Silverlight jobs are in demand and will only become moreso as companies target Windows Phone 7 and cross-platform applications that leverage existing .NET assets.

WinForms to WPF - How do we get there from here?

7 votes

Is there a practical way for us to slowly evolve a WinForms application to WPF without creating a support nightmare for ourselves with strange interop scenarios?

Background info:

We have a large battleship gray WinForms application that is heavily used by an internal group of about 60-75 users. We're starting to run into places where we could see some benefit from having the app in WPF, but it's not enough to justify a large project to completely re-write it. All of the screens in the app are self contained WinForms user controls and the WinForms app is just a shell that handles menuing, opening/closing forms, provides some shared helper methods, etc...

Thus far, the best idea we've had is to convert the shell application to WPF and then host the WinForms user controls inside it. We thought that we could then convert the user controls over time, tieing those changes to initiatives that have enough business value to support the additional work. I'm concerned about how well the interop works and how it will impact performance. I'm also concerned about how we transition to a new look for the app. It would seem odd to make the shell app look snazzy and then have old battleship gray user controls hosted inside it and it also seems odd to create the shell app in WPF and make it look just like it did in WinForms.

If one of the Caliburn, Prism, or another similar framework would ease the transition, we'd be open to exploring those options as well.

We were in a similar situation and chose the following path: At the beginning we started to host a few WPF windows in the application shell (still WinForms). Of course there was some visible difference but we reduced the difference deliberately by toning down the new windows. We figured that by the time we would convert the remaining windows/controls it will be easier to "upgrade" to a more vivid experience since the UI will be entirely WPF and we can involve a graphical designer to work their magic based on XAML.

We have now reached the point where the majority of the windows are WPF. We have started the process of converting the WinForms shell app into a WPF based shell application hosting the remaining WinForms. We sill have sort of dull colors but users have started to notice the difference and although it is small our users still like the incremental positive change. Not too long and we will retire the last WinForm. That will be the point when we let our graphical designers off the leash!

As to performance: I can certainly not make a general statement as it heavily depends on your particular controls/windows. In our product (several hundred windows) we haven't found any significant performance issue related to the mix of WPF and WinForms.

We didn't look into any of the frameworks, so I'm afraid I cannot comment on those.

Should a WPF application be written in C++ or C#?

7 votes

WPF applications are, at its core, managed applications? Right? So, I have to choose between using managed C++ or managed C#. I experimented with managed C++ years ago. It seemed to be not quite be ready for primetime. I'm guessing Microsoft has put more effort into managed C# than managed C++. So, it seems like using managed C# is the best alternative between the two. Is this the case? What experiences have you had with WPF in either language? Thanks in advance.

Firstly: managed C++ has been replaced by C++/CLI, and "managed C#" is just C#.

I would strongly recommend you to use C# for a new project, and use C++/CLI only when needed. C# has a better support, has a larger user base, and is easier to work with inside Visual Studio 2010.

Additionally, keep in mind that C++ and C++/CLI are two different languages. For my first .Net project, I chose C++/CLI because I already knew C++, and this was a very bad idea: the learning curve from C++ to C++/CLI is similar to learning C# from C++: don't fall in that trap like I did.

WPF TabControl - Add New Tab Button (+)

7 votes

What is the proper way of adding a '+' button tab at the end of all the tab items in the tab strip of a tab control.

  1. It should work correctly with multiple tab header rows.
  2. It should be at the end of all tab items
  3. Tab cycling should work correctly (Alt+Tab) ie the + tab should be skipped.
  4. I shouldn't have to modify the source collection I am binding to. ie the control should be reuseable.
  5. Solution should work with MVVM

alt text

alt text

EDIT: To be more precise, the button should appear exactly as an additional last tab and not as a separate button somewhere on the right of all tab strip rows.

I am just looking for the general approach to doing this.

Google throws many examples of this, but if you dig a little deep none of them satisfy all the above four points.

Any help greatly appreciated.

N

An almost complete solution using IEditableCollectionView:

    ObservableCollection<ItemVM> _items;
    public ObservableCollection<ItemVM> Items
    {
        get
        {
            if (_items == null)
            {
                _items = new ObservableCollection<ItemVM>();
                var itemsView = (IEditableCollectionView)CollectionViewSource.GetDefaultView(_items);
                itemsView.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtEnd;
            }

            return _items;
        }
    }

    private DelegateCommand<object> _newCommand;
    public DelegateCommand<object> NewCommand
    {
        get
        {
            if (_newCommand == null)
            {
                _newCommand = new DelegateCommand<object>(New_Execute);
            }

            return _newCommand;
        }
    }

    private void New_Execute(object parameter)
    {
        Items.Add(new ItemVM());
    }

<DataTemplate x:Key="newTabButtonContentTemplate">
    <Grid/>
</DataTemplate>

<DataTemplate x:Key="newTabButtonHeaderTemplate">
    <Button Content="+"
        Command="{Binding ElementName=parentUserControl, Path=DataContext.NewCommand}"/>
</DataTemplate>

<DataTemplate x:Key="itemContentTemplate">
    <Grid/>
</DataTemplate>

<DataTemplate x:Key="itemHeaderTemplate">
    <TextBlock Text="TabItem_test"/>
</DataTemplate>

<vw:ItemHeaderTemplateSelector x:Key="headerTemplateSelector"
                           NewButtonHeaderTemplate="{StaticResource newTabButtonHeaderTemplate}"
                           ItemHeaderTemplate="{StaticResource itemHeaderTemplate}"/>

<vw:ItemContentTemplateSelector x:Key="contentTemplateSelector"
                            NewButtonContentTemplate="{StaticResource     newTabButtonContentTemplate}"
                            ItemContentTemplate="{StaticResource itemContentTemplate}"/>

<TabControl ItemsSource="{Binding Items}"
        ItemTemplateSelector="{StaticResource headerTemplateSelector}"
        ContentTemplateSelector="{StaticResource contentTemplateSelector}"/>


public class ItemHeaderTemplateSelector : DataTemplateSelector
{
    public DataTemplate ItemHeaderTemplate { get; set; }
    public DataTemplate NewButtonHeaderTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == CollectionView.NewItemPlaceholder)
        {
            return NewButtonHeaderTemplate;
        }
        else
        {
            return ItemHeaderTemplate;
        }
    }
}



public class ItemContentTemplateSelector : DataTemplateSelector
{
    public DataTemplate ItemContentTemplate { get; set; }
    public DataTemplate NewButtonContentTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == CollectionView.NewItemPlaceholder)
        {
            return NewButtonContentTemplate;
        }
        else
        {
            return ItemContentTemplate;
        }
    }
}

enter code here

Its almost complete because the tab cycle doesnt skip the '+' tab, and will show empty content (which is not exactly great but I can live with it until a better solution come around... ).

WPF Best Practices: Do custom controls work well with the MVVM design?

7 votes

I was looking at creating a common control that I will be able to reuse on my pages: an AddressControl which has Address1, Address2, City, State, Zip, etc...

Originally I just created a class (AddressEntity) that contained all these items and implemented INotifyPropertyChanged. I included that class as a DependencyProperty in my Code-Behind for the AddressControl and used it as the DataContext for the bindings to its properties.

Then, someone said my code was ugly and I should look into MVVM. Looking at it, I assume that:

  • AddressEntity.cs will just be a container of data (i.e. Address1, Address2, etc.) and members (i.e. Clone, ToString, etc.)
  • I need some AddressViewModel to wrap my AddressEntity in and provide the PropertyNotification Changes, Validation, etc.
  • I need to somehow have a "View" for this.

The problem is every example I've ever seen has a UserControl as the View and not a CustomControl. Before I delve too deep into this...

  • Is it possible to use MVVM + Custom Controls for this example?
  • Is it pretty much the same thing (UserControl vs CustomControl) as the View with the exception of primary differences of UserControl vs CustomControl? Basically, is my CustomControl really just a View?

References: HE MODEL-VIEW-VIEWMODEL (MVVM) DESIGN PATTERN FOR WPF

CustomControls are never done with mvvm.

What you want is a reusable view(user control) of your data and not a control.

UserControls and CustomControls are two completely different beasts.

EDIT:

Notwithstanding why UserControls were originally developed, in MVVM typically you use a UserControl when you want a reuseable view which is specific to your model/viewmodel. Its just XAMl without any code behind (except for the auto generated InitializeComponent stuff). Generally you keep a UserControl in the same project that you use it in.

You go for a CustomControl when you want a generic piece of functionality which requires a view and which has potential use even outside the scope of your current application. Here the control is actually defined in a code file and the look (which can be overriden) comes via XAML in a resource dictionary. Generally you keep a CustomControl in a a seperate ControlLibrary project and reference the library in the project you wish to use it in.

With due respect to WallStreetProgrammer, choosing between a user control and a custom control based solely on whether or not you want a lookless control is a bit naive.

Is normalizing the gender table going too far?

6 votes

I am not a database guy, but am trying to clean up another database. So my question is would normalizing the gender table be going too far?

User table:
userid int pk,
genderid char(1) fk
etc...

gender table:
genderid char(1) pk,
gender varchar(20)

Now at first it seemed silly to me, but then I considered it because i can then have a constant data source to populate from or bind from. I will be using WPF. If it was another framework I would probably avoid it, but what do you think?

Whether or not you choose to normalize your table structure to accomodate gender is going to depend on the requirements of your application and your business requirements.

I would normalize if:

  • You want to be able to manage the "description" of a gender in the database, and not in code.
    • This allows you to quickly change the description from Man/Woman to Male/Female, for example.
  • Your application currently must handle, or will possible handle in the future, localization requirements, i.e. being able to specify gender in different languages.
  • Your business requires that everything be normalized.

I would not normalize if:

  • You have a relatively simple application where you can easily manage the description of the gender in code rather than in the database.
  • You have tight programmatic control of the data going in and out of the gender field such that you can ensure consistency of the data in that field.
  • You only care about the gender field for information capture, meaning, you don't have a lot of programmatic need to update this field once it is set the first time.

treeview Multibinding in wpf

6 votes

I want to bind a treeview to a class like this one:

public class Folder : Base_FileFolder
{
    public Folder()
    {
        Folders = new ObservableCollection<Folder>();
        Files = new ObservableCollection<File>();
    }
    public ObservableCollection<Folder> Folders { get; set; }
    public ObservableCollection<File> Files { get; set; }
}

the other classes ares:

public class File : Base_FileFolder
{
}

public class Base_FileFolder : DependencyObject
{
    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
    public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Base_FileFolder), new UIPropertyMetadata(""));
}

How can I create a treeview that shows Files and Folders collection

I want to use something like this:

 <HierarchicalDataTemplate
 DataType="{x:Type model:Folder}"
 ItemsSource="{Binding Childs}">   
 <DockPanel>
       <Label Content="{Binding Name}"/>    </DockPanel>
 </HierarchicalDataTemplate>

so I get Somethign like this:

rootFolder

|
|-File
|-File
|-Folder
  |-File
  |-File
  |-Folder
    |-File

What exactly is your question? How to combine them? CompositeCollection.

EDIT: as mentioned in the comments, my Intuipic application does something very similar to what you're requesting. Here's a screenshot:

alt text

HTH,
Kent

What is the WPF equivalent to "System.Windows.Forms.Application.X" for obtaining startup path, app data path, etc.?

6 votes

I'm converting a windows forms application to a WPF application. Is there a way to obtain things like, Startup Path, User App Data Path, Common App Data Path, etc. without referencing System.Windows.Forms?

Previously, I used System.Windows.Forms.Application.StartupPath, but the System.Windows.Application.Current object doesn't contain the same information.

You might want to look at System.Environment.GetFolderPath.

The values of the SpecialFolder enum are numerous:

ApplicationData
CommonApplicationData
CommonProgramFiles
Cookies
Desktop
DesktopDirectory
Favorites
History
InternetCache
LocalApplicationData
MyComputer
MyDocuments
MyMusic
MyPictures
Personal
ProgramFiles
Programs
Recent
SendTo
StartMenu
Startup
System
Templates

Is that helpful?

WPF - Expand Window to the Left

6 votes

I have a WPF window with expandable panel (via Expander). The panel is on the left side of the window, and when expanded the window grows to fit the content.

By default, windows are anchored to the top-left, so my window grows to the right. I'd like the window to grow to the left.

I tried to do the following in the Window.SizeChanged event:

private void onWindowSizeChanged(object sender, SizeChangedEventArgs e)
{
    Left -= (e.NewSize.Width - e.PreviousSize.Width)
}

and it works, but the growth is jerky, and I'd like to find a smoother solution.

I managed to overcome this using a simple solution: Hide & Show. Here's the code:

protected override void OnRenderSizeChanged(SizeChangeInfo sizeInfo)
{
    if (!sizeInfo.WidthChanged)
    {
        base.OnRenderSizeChanged(sizeInfo);
        return;
    }
    Hide();
    base.OnRenderSizeChanged(sizeInfo);
    Left -= (sizeInfo.NewSize.Width - sizeInfo.PreviousSize.Width);
    Show();
}

I replaced the event handler for Window.SizeChanged with this override of FrameworkElement.OnRenderSizeChanged.

looking for stock charting component

5 votes

i am writing a financial WPF desktop application and i am looking for a component that would allow me to display (and print) OHLC, candlestick, and possibly other types of financial charts. I need to be able to embed custom graphics into the chart, i mean graphics such as extra lines, additional charts, etc. the component needs to support overlaying of different chart types as well. and it has to look professional, unlike these 3D charts that I have seen on codeplex. any help would be appreciated.

thanks konstantin

Updated

Here are some recommendations:

I'm a sucker for free stuff, but if you're working for a company that has extra cash to shell out at the most fancy stuff out there, then you can try StockChart SL, otherwise it looks like Visfire should do it for you.