Question

I'm using WPF and found that MVVM is most commonly used with WPF, encouraging to move the presentation logic into ViewModel and keep the code-behind at minimum.

However after some time I found myself putting more logic into view and doing these kind of stuff in view (XAML):

1 - Constructing string from multiple elements:

<TextBlock>
    <Run Text="{Binding Prop1}" />
    <!--<Run Combined with string.Format />-->
    <Run Text="," />
    <Run Text="{Binding Prop2}" />
</TextBlock>

2 - Moving conditional logic into data triggers:

<TextBox>
    <TextBox.Resources>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeProperty}" Value="value1">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
                <DataTrigger Binding="{Binding SomeProperty}" Value="value2">
                    <Setter Property="Visibility" Value="Collapsed" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Resources>
</TextBox>

3 - Using ContentControl combined with multiple data templates for different type contents:

<UserControl.Resources>
    <DataTemplate x:Key="Template1" >
        <ContentControl HorizontalContentAlignment="Stretch" Content="{Binding Item}">
            <ContentControl.Resources>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding HasAnyItem}" Value="True">
                            <Setter Property="ContentTemplate" Value="{DynamicResource Template2}" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding HasAnyItem}" Value="False">
                            <Setter Property="ContentTemplate" Value="{DynamicResource Template1}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Resources>
        </ContentControl>
    </DataTemplate>

    <DataTemplate x:Key="Template2" >
        ...
    </DataTemplate>
<UserControl.Resources>
...
<ContentControl ContentTemplate="{StaticResource Template1}"  Content="{Binding}"/>

and this list continues, but I assume that you get the general idea of what kind of stuff I'm talking about. I'm aware that some of these features are somehow the beauty of WPF.

But when it comes to maintainability and flexibility, Is there a better way of logic handling? Does it make my UI more than enough smart, which was an anti-pattern in the windows form days?

Was it helpful?

Solution

Nice thought, for me the idea is mainly what is testable and how to write tests for it. Most of the times ViewModel is not a direct (one-on-one) correspondence for your presentation (View).

The idea where a designer designs your view using XAML (Blend/Designer) to me indicates that there is no business logic in that for them the business object definition is necessary.

When you have unit tests then you can prove that it is maintainable.

So all the things you mentioned if they are purely presentation then I would not really mind. But if that impacts the state of business data then I would rather have that in ViewModel and use converters for appropriate presentation

OTHER TIPS

Totally agree with bjoshi, base line is no business logic on the XAML. I would like to add another three points you can consider:

  1. Performance. When you put more logic on XAML and make UI more powerful, you also bring in the potential of performance hit. In your example, "Run" is not recommended way from performance perspective. Also you use DynamicResource in your third example, which might be also avoided if you could find an approach using StaticResource instead.

  2. Debugging. Debugging might be one of the disadvantages of WPF since WPF manages data binding, triggers, etc for you and these things are indirect. For example how you debug triggers? If the view is simple and passive, it also might be easier to debug.

  3. Flexibility. In the first example, you put logic of organizing Pro1 and Pro2 on view rather on view model. Assuming in future you would like change "," to ":", for example, you have to modify the view. This case is simple but others might be difficult. Surely neither case will be unit-testable. You might need to forecast the change and complexity of change.

Hope it can help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top