WPF Generic Save/Undo/Delete/Add buttons

WPF Generic Save/Undo/Delete/Add buttons

Old forum URL: forums.lhotka.net/forums/t/8550.aspx


jamie.clayton posted on Wednesday, February 17, 2010

I've got a simple WPF screen for editing Sofware options. It just loads an EditableRoot Business object at record one.  I've got a codeless form and was working on the Save/Undo/Add buttons. Here is the sample XAML. I haven't got a delete/add button in this sample.

I want to make the Save/Undo (Add and delete) buttons reusable, but the ApplicationCommands.Action statement require binding to the CSLA object.  How do I change the Buttons XAML CommandTarget="{Binding Source={StaticResource SoftwareOptions}, Path=CommandManager,                                         BindsDirectlyToSource=True}" to something generic, so it just uses the windows datacontext binding?

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <csla:ObjectStatus >
                    <csla:Authorizer Name="AuthPanel">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                            <CheckBox
                            IsEnabled="False"
                            IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=csla:ObjectStatus, AncestorLevel=1}, Path=IsSavable}">IsSavable</CheckBox>
                            <CheckBox
                            IsEnabled="False"
                            IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=csla:ObjectStatus, AncestorLevel=1}, Path=IsValid}">IsValid</CheckBox>
                            <CheckBox
                            IsEnabled="False"
                            IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=csla:ObjectStatus, AncestorLevel=1}, Path=IsDirty}">IsDirty</CheckBox>
                            <CheckBox
                            IsEnabled="False"
                            IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=csla:ObjectStatus, AncestorLevel=1}, Path=IsNew}">IsNew</CheckBox>
                            <Button
                            Content="Save"
                            Command="ApplicationCommands.Save"
                            CommandTarget="{Binding Source={StaticResource SoftwareOptions}, Path=CommandManager,             BindsDirectlyToSource=True}"
                            HorizontalAlignment="Left" IsDefault="True"/>
                            <Button
                                Content="Undo"
                                Command="ApplicationCommands.Undo"
                                CommandTarget="{Binding Source={StaticResource SoftwareOptions}, Path=CommandManager,                                          BindsDirectlyToSource=True}"
                                HorizontalAlignment="Left"
                                IsCancel="True"/>
                            <!--TODO: Review why Command="ApplicationCommands.Close" can be used for close button (codeless). Button is alway disabled. -->
                            <Button Name="CloseButton"
                                Content="E_xit"                                                                
                                HorizontalAlignment="Left"
                                IsEnabled="True" />
                        </StackPanel>
                    </csla:Authorizer>
                </csla:ObjectStatus>
            </StackPanel>

 

 

RockfordLhotka replied on Wednesday, February 17, 2010

This is where commanding really falls down.

In CSLA 3.8 and higher you can use InvokeMethod or Execute - which do the same thing in slightly different ways - to replace commanding and execute methods on the DataContext.

Though that still won't work with the WPF CslaDataProvider, because it doesn't (can't) directly expose verbs like that. The data provider model just isn't designed along those lines.

But what you can do instead is use a viewmodel object instead of a data provider. That's not a huge shift, at least in a basic sense, since 3.8 includes the ViewModel<T> base class that makes it reasonably easy to create something sort of like a CslaDataProvider, but that works with InvokeMethod or Execute to call methods based on UI events like a Button Click event.

jamie.clayton replied on Wednesday, February 17, 2010

Rocky,

Thanks for the guidence. Will review your notes on MVVM. Thanks to Blakes work on the Codesmith CSLA templates, I'm using 3.8.2. Don't supose you have an XAML example?

RockfordLhotka replied on Wednesday, February 17, 2010

The MVVMExperiment sample in the Samples download is a pretty basic sample that shows some of the concepts.

Copyright (c) Marimer LLC