70 likes | 199 Vues
This article delves into effective techniques for structuring WPF applications using XAML and C++/CLI. It highlights the importance of leveraging XAML for layout and data binding while keeping code-behind for commands and event handling. The guide covers event and command binding, data context, and practical advice such as the benefits of avoiding unnecessary complexity. Learn best practices for merging C# and C++/CLI in WPF to enhance application functionality and maintainability while offering examples and insights for practical implementation.
E N D
WPF Layer CakeC#, C++/CLI and C Andy Dent www.andydent.com May 2009
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
<Window.CommandBindings> <CommandBinding 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> <MenuDockPanel.Dock="Top"> <MenuItem Header="_File" > <MenuItem Header="E_xit" Command="Close" /> </MenuItem> <MenuItem Header="Test"> <MenuItem Command="{x:Static w:TestDespatchWindow.cmdShow2}" /> </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" Command="{x:Static w:TestDespatchWindow.cmdShow2}" Margin="10,2,10,2" Content="Show2 via WPF"/> <Button x:Name="Show2IndirectCommand" Margin="10,2,10,2" Content="Show2 via DLL" />
publicpartialclassWindowWithCommandVM : Window { publicWindowWithCommandVM() { InitializeComponent(); mBackend = newBackedCommandViewModel( "Fred Nerk", "10 Bloggs Ave\nToon Town", true); ... DataContext = mBackend; NameEntry.SetBinding( TextBox.TextProperty, newBinding("Name") {Mode = BindingMode.TwoWay} ); ... CNTL_Lower.Command = mBackend.cmdLower; CommandBindings.Add( newCommandBinding(mBackend.cmdLower, mBackend.CommandSingleEntryPoint) );
publicrefclassBackedCommandViewModel : publicINotifyPropertyChanged { public: BackedCommandViewModel( String^ _name, String^ _address); ... voidCommandSingleEntryPoint( Object^ sender, ExecutedRoutedEventArgs^ e); property String^ Name { String^ get(); void set(String^ s); }; property String^ Address { String^ get();... propertyRoutedCommand^ cmdLower { RoutedCommand^ get(); };... virtualeventPropertyChangedEventHandler^ PropertyChanged; private: voidOnPropertyChanged(String^ name) { PropertyChanged(this, gcnewPropertyChangedEventArgs(name)); }
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