Download presentation
1
WPF Layer Cake C#, C++/CLI and C
Andy Dent May 2009
2
Background Clunky old C, must be preserved with strong OO design and lots of code coupled to data. New GUI required. Rich Internet App is appealing for future. Long-term change – core IP of company.
3
Clunky old C, must be preserved with strong OO design and lots of code coupled to data.
New GUI required. Rich Internet App is appealing for future. Long-term change – core IP of company. ViewModel = all state of the GUI preserved in an external object so GUI is very lightweight, makes testing possible as can invoke all state changes through ViewModel interface.
4
Wandering in WPF Continuum of structuring a WPF program:
Ain’t it cool – do as much in XAML as possible, binding data and all commands/events. Events bound in XAML, commands in code. Bind data only in XAML. XAML for layout, code for all bindings. Silly opposite extreme – no XAML I have a natural tendency to using a declarative style and there is a certain geeky appeal to doing as much as possible in XAML.
5
<Window.CommandBindings>
Command="{x:Static w:TestDespatchWindow.cmdShow2}" Executed="OnShow2" /> </Window.CommandBindings> <Window.InputBindings> <KeyBinding Key="T" Modifiers="Control" Command="{x:Static w:TestDespatchWindow.cmdShow2}" /> </Window.InputBindings> <DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="_File" > <MenuItem Header="E_xit" Command="Close" /> </MenuItem> <MenuItem Header="Test"> <MenuItem </Menu> <StackPanel Margin="0,8,0,0"> <Button x:Name="Show2EventBased" Margin="10,2,10,2" Click="OnShow2" Content="Show2 via WPF Event"/> <Button x:Name="Show2Command" Margin="10,2,10,2" Content="Show2 via WPF"/> <Button x:Name="Show2IndirectCommand" Margin="10,2,10,2" Content="Show2 via DLL" />
6
public partial class WindowWithCommandVM : Window
{ public WindowWithCommandVM() InitializeComponent(); mBackend = new BackedCommandViewModel( "Fred Nerk", "10 Bloggs Ave\nToon Town", true); ... DataContext = mBackend; NameEntry.SetBinding( TextBox.TextProperty, new Binding("Name") {Mode = BindingMode.TwoWay} ); CNTL_Lower.Command = mBackend.cmdLower; CommandBindings.Add( new CommandBinding(mBackend.cmdLower, mBackend.CommandSingleEntryPoint) );
7
public ref class BackedCommandViewModel :
public INotifyPropertyChanged { public: BackedCommandViewModel( String^ _name, String^ _address); ... void CommandSingleEntryPoint( Object^ sender, ExecutedRoutedEventArgs^ e); property String^ Name { String^ get(); void set(String^ s); }; property String^ Address { String^ get();... property RoutedCommand^ cmdLower { RoutedCommand^ get(); };... virtual event PropertyChangedEventHandler^ PropertyChanged; private: void OnPropertyChanged(String^ name) PropertyChanged(this, gcnew PropertyChangedEventArgs(name)); }
8
Lessons Learned Don’t fight C# - do hookups of properties and commands in code-behind files. C++/CLI can define straightforward Property objects, events, delegates and commands. Debugging all the way works if you tell your app it should debug unmanaged code. Beware of #includes in C++/CLI – use referenced assemblies C2011 'class' type redefinition The common error C2011 occurs normally because people forget to have ifndef/define guards or pragma once.Error 1 error C2011: 'CPPDemoViewModel::SimpleViewModel' : 'class' type redefinition However, the simplest initial version of CPPViewModelTest testing CPPDemoViewModel came up with the C2011 error. Because this is a common beginners error, it is virtually impossible to find an answer on Google. I did find one instance of someone triggering it in the same circumstances (in Sep 2008) but nobody had provided a useful answer. The key turned out to be the traditional include "CPPDemoViewModel.h" which brings the class definitions of namespace CPPViewModelTest into UnitTest_CPPViewModel.cpp as you would for any C++ compilation using a library. CPPViewModelTest is defined in the assembly CPPDemoViewModel and that assembly is explicitly recorded as a Reference of the project CPPViewModelTest. The reference imports the namespace into the list of available namespaces but does not trigger the pragma once protection (which I regard as a C++/CLI compilation bug). Hence the C2011 occurring as if the class definition wasn't guarded. Note that the project CPPViewModelTest also has a dependency on the project CPPDemoViewModel which is there to guarantee builds are triggered. Tests Fail with System.IO.FileNotFoundException This is the for specific circumstance when a pure C DLL is included in a C# assembly - it doesn't get propagated from the C++/CLI assembly which uses it, despite settings to copy dependents.It will build OK but get a runtime System.IO.FileNotFoundException as described here because of a failure to find BackingStore.dll. This was fixed by adding a test configuration (right-click Solution - Add) ConfigRequiringBackingStore which specifies that BackingStored.dll must be deployed.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.