Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Windows Presentation Foundation (WPF) ger en omfattande miljö för att skapa program. Men när du har en betydande investering i Win32-kod kan det vara mer effektivt att lägga till WPF-funktioner i ditt program i stället för att skriva om din ursprungliga kod. WPF tillhandahåller en enkel mekanism för att hantera WPF-innehåll i ett Win32-fönster.
I den här självstudien beskrivs hur du skriver ett exempelprogram, Hosting WPF Content in a Win32 Window Sample, som är värd för WPF-innehåll i ett Win32-fönster. Du kan utöka det här exemplet för att hantera valfritt Win32-fönster. Eftersom det handlar om att blanda hanterad och ohanterad kod skrivs programmet i C++/CLI.
Kravspecifikation
Den här handledningen förutsätter grundläggande kännedom om både WPF- och Win32-programmering. En grundläggande introduktion till WPF-programmering finns i Komma igång. För en introduktion till Win32-programmering bör du referera till någon av de många böckerna i ämnet, särskilt Programmeringsfönster av Charles Petzold.
Eftersom exemplet som medföljer den här självstudien implementeras i C++/CLI förutsätter den här självstudien att du är bekant med användningen av C++ för att programmera Windows-API:et plus en förståelse för programmering av hanterad kod. Att känna till C++/CLI är användbart men inte nödvändigt.
Anmärkning
Den här handledningen innehåller ett antal kodexempel från den associerade exempelsamlingen. För läsbarhet innehåller den dock inte den fullständiga exempelkoden. Den fullständiga exempelkoden finns i Hosting WPF Content in a Win32 Window Sample (Exempel för att värda WPF-innehåll i ett Win32-fönster).
Den grundläggande proceduren
I det här avsnittet beskrivs den grundläggande procedur som du använder för att vara värd för WPF-innehåll i ett Win32-fönster. I de återstående avsnitten förklaras information om varje steg.
Nyckeln till att vara värd för WPF-innehåll i ett Win32-fönster är HwndSource klassen. Den här klassen omsluter WPF-innehållet i ett Win32-fönster så att det kan införlivas i användargränssnittet (UI) som ett underordnat fönster. Följande metod kombinerar Win32 och WPF i ett enda program.
Implementera DITT WPF-innehåll som en hanterad klass.
Implementera ett Windows-program med C++/CLI. Om du börjar med ett befintligt program och ohanterad C++-kod kan du vanligtvis aktivera det för att anropa hanterad kod genom att ändra projektinställningarna så att de
/clrinnehåller kompilatorflaggan.Ställ in trådningsmodellen på entrådad lägenhet (STA).
Hantera WM_CREATE-meddelandeti fönsterproceduren och gör följande:
Skapa ett nytt HwndSource objekt med det överordnade fönstret som parameter
parent.Skapa en instans av WPF-innehållsklassen.
Tilldela en referens till WPF-innehållsobjektet till RootVisual egenskapen för HwndSource.
Hämta HWND för innehållet. Egenskapen Handle för HwndSource objektet innehåller fönsterhandtaget (HWND). Om du vill hämta en HWND som du kan använda i den ohanterade delen av ditt program kan du casta
Handle.ToPointer()till en HWND.
Implementera en hanterad klass som innehåller ett statiskt fält för att lagra en referens till ditt WPF-innehåll. Med den här klassen kan du hämta en referens till WPF-innehållet från din Win32-kod.
Tilldela WPF-innehållet till det statiska fältet.
Ta emot meddelanden från WPF-innehållet genom att koppla en hanterare till en eller flera AV WPF-händelserna.
Kommunicera med WPF-innehållet med hjälp av referensen som du lagrade i det statiska fältet för att ange egenskaper och så vidare.
Anmärkning
Du kan också använda WPF-innehåll. Du måste dock kompilera den separat som ett DLL-bibliotek (Dynamic Link Library) och referera till DLL:en från ditt Win32-program. Resten av proceduren liknar den som beskrivs ovan.
Implementera värdprogrammet
I det här avsnittet beskrivs hur du är värd för WPF-innehåll i ett grundläggande Win32-program. Själva innehållet implementeras i C++/CLI som en hanterad klass. För det mesta är det enkel WPF-programmering. Viktiga aspekter av innehållsimplementeringen beskrivs i Implementering av WPF-innehållet.
Det grundläggande programmet
Startpunkten för värdprogrammet var att skapa en Visual Studio 2005-mall.
Öppna Visual Studio 2005 och välj Nytt projekt på menyn Arkiv .
Välj Win32 i listan över Visual C++-projekttyper. Om standardspråket inte är C++, hittar du dessa projekttyper under Andra språk.
Välj en Win32-projektmall , tilldela ett namn till projektet och klicka på OK för att starta win32-programguiden.
Acceptera guidens standardinställningar och klicka på Slutför för att starta projektet.
Mallen skapar ett grundläggande Win32-program, inklusive:
En startpunkt för applikationen.
Ett fönster med en associerad fönsterprocedur (WndProc).
En meny med rubrikerna Arkiv och Hjälp . Arkiv-menyn har ett exit-objekt som stänger programmet. Hjälp-menyn har ett Om-objekt som startar en enkel dialogruta.
Innan du börjar skriva kod som värd för WPF-innehållet måste du göra två ändringar i den grundläggande mallen.
Den första är att kompilera projektet som hanterad kod. Som standard kompileras projektet som ohanterad kod. Men eftersom WPF implementeras i hanterad kod måste projektet kompileras i enlighet med detta.
Högerklicka på projektnamnet i Solution Explorer och välj Egenskaper på snabbmenyn för att starta dialogrutan Egenskapssidor .
Välj Konfigurationsegenskaper i trädvyn i den vänstra rutan.
Välj Stöd för Common Language Runtime i listan Project Defaults i den högra rutan.
Välj Common Language Runtime Support (/clr) i listrutan.
Anmärkning
Med den här kompileringsflaggan kan du använda hanterad kod i ditt program, men den ohanterade koden kompileras fortfarande som tidigare.
WPF använder trådningsmodellen för enkeltrådad lägenhet (STA). För att fungera korrekt med WPF-innehållskoden måste du ange programmets trådningsmodell till STA genom att tillämpa ett attribut på startpunkten.
[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
Värd för WPF-innehållet
WPF-innehållet är ett enkelt adressinmatningsprogram. Den består av flera TextBox kontroller för att ta användarnamn, adress och så vidare. Det finns också två Button kontroller, OK och Avbryt. När användaren klickar på OK samlar knappens Click händelsehanterare in data från TextBox kontrollerna, tilldelar dem till motsvarande egenskaper och skapar en anpassad händelse, OnButtonClicked. När användaren klickar på Avbryt, utför hanteraren helt enkelt åtgärdenOnButtonClicked. Händelseargumentobjektet för OnButtonClicked innehåller ett booleskt fält som anger vilken knapp som klickades.
Koden som ska vara värd för WPF-innehållet implementeras i en hanterare för WM_CREATE-meddelandet i värdfönstret.
case WM_CREATE :
  GetClientRect(hWnd, &rect);
  wpfHwnd = GetHwnd(hWnd, rect.right-375, 0, 375, 250);
  CreateDataDisplay(hWnd, 275, rect.right-375, 375);
  CreateRadioButtons(hWnd);
break;
Metoden GetHwnd tar storleks- och positionsinformation plus det överordnade fönsterhandtaget och returnerar fönsterhandtaget för det värdbaserade WPF-innehållet.
Anmärkning
Du kan inte använda ett #using direktiv för System::Windows::Interop namnområdet. Detta skapar en namnkollision mellan MSG strukturen i namnområdet och MSG-strukturen som deklareras i winuser.h. Du måste i stället använda fullständigt kvalificerade namn för att få åtkomst till innehållet i namnområdet.
HWND GetHwnd(HWND parent, int x, int y, int width, int height)
{
    System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters(
    "hi" // NAME
    );
    sourceParams->PositionX = x;
    sourceParams->PositionY = y;
    sourceParams->Height = height;
    sourceParams->Width = width;
    sourceParams->ParentWindow = IntPtr(parent);
    sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; // style
    System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams);
    WPFPage ^myPage = gcnew WPFPage(width, height);
    //Assign a reference to the WPF page and a set of UI properties to a set of static properties in a class
    //that is designed for that purpose.
    WPFPageHost::hostedPage = myPage;
    WPFPageHost::initBackBrush = myPage->Background;
    WPFPageHost::initFontFamily = myPage->DefaultFontFamily;
    WPFPageHost::initFontSize = myPage->DefaultFontSize;
    WPFPageHost::initFontStyle = myPage->DefaultFontStyle;
    WPFPageHost::initFontWeight = myPage->DefaultFontWeight;
    WPFPageHost::initForeBrush = myPage->DefaultForeBrush;
    myPage->OnButtonClicked += gcnew WPFPage::ButtonClickHandler(WPFButtonClicked);
    source->RootVisual = myPage;
    return (HWND) source->Handle.ToPointer();
}
Du kan inte vara värd för WPF-innehållet direkt i programfönstret. I stället skapar du först ett HwndSource objekt för att omsluta WPF-innehållet. Det här objektet är i princip ett fönster som är utformat för att vara värd för ett WPF-innehåll. Du värdar HwndSource-objektet i det överordnade fönstret genom att skapa det som ett barn till ett Win32-fönster som är en del av ditt program. Konstruktorparametrarna HwndSource innehåller ungefär samma information som du skickar till CreateWindow när du skapar ett Win32-underordnat fönster.
Sedan skapar du en instans av WPF-innehållsobjektet. I det här fallet implementeras WPF-innehållet som en separat klass, WPFPage, med C++/CLI. Du kan också implementera WPF-innehållet med XAML. Men för att göra det måste du konfigurera ett separat projekt och skapa WPF-innehållet som en DLL. Du kan lägga till en referens till DLL:en i projektet och använda den referensen för att skapa en instans av WPF-innehållet.
Du visar WPF-innehållet i det underordnade fönstret genom att tilldela en referens till WPF-innehållet till RootVisual egenskapen hos HwndSource.
Nästa kodrad kopplar en händelsehanterare, WPFButtonClicked, till WPF-innehållshändelsen OnButtonClicked . Den här hanteraren anropas när användaren klickar på knappen OK eller Avbryt . Mer information om den här händelsehanteraren finns i kommunicera_med_WPF-dokumentationen.
Den sista kodraden som visas returnerar det fönsterhandtag (HWND) som är associerat med HwndSource objektet. Du kan använda det här handtaget från din Win32-kod för att skicka meddelanden till det värdbaserade fönstret, även om exemplet inte gör det. Objektet HwndSource genererar en händelse varje gång det tar emot ett meddelande. Om du vill bearbeta meddelandena anropar AddHook du metoden för att bifoga en meddelandehanterare och bearbetar sedan meddelandena i den hanteraren.
Hålla en referens till innehåll i WPF
För många program vill du kommunicera med WPF-innehållet senare. Du kanske till exempel vill ändra WPF-innehållsegenskaperna eller kanske ha HwndSource objektet som värd för ett annat WPF-innehåll. För att göra detta behöver du en referens till HwndSource objektet eller WPF-innehållet. Objektet HwndSource och dess tillhörande WPF-innehåll finns kvar i minnet tills du förstör fönsterhandtaget. Variabeln som du tilldelar objektet HwndSource kommer dock att gå utanför omfånget så snart du kommer tillbaka från fönsterproceduren. Det vanliga sättet att hantera det här problemet med Win32-program är att använda en statisk eller global variabel. Tyvärr kan du inte tilldela ett hanterat objekt till dessa typer av variabler. Du kan tilldela fönsterhandtaget som är associerat med HwndSource objektet till en global eller statisk variabel, men som inte ger åtkomst till själva objektet.
Den enklaste lösningen på det här problemet är att implementera en hanterad klass som innehåller en uppsättning statiska fält som innehåller referenser till alla hanterade objekt som du behöver åtkomst till. Exemplet använder WPFPageHost klassen för att innehålla en referens till WPF-innehållet, plus de inledande värdena för ett antal av dess egenskaper som kan ändras senare av användaren. Detta definieras i rubriken.
public ref class WPFPageHost
{
public:
  WPFPageHost();
  static WPFPage^ hostedPage;
  //initial property settings
  static System::Windows::Media::Brush^ initBackBrush;
  static System::Windows::Media::Brush^ initForeBrush;
  static System::Windows::Media::FontFamily^ initFontFamily;
  static System::Windows::FontStyle initFontStyle;
  static System::Windows::FontWeight initFontWeight;
  static double initFontSize;
};
Den senare delen av GetHwnd-funktionen tilldelar värden till dessa fält för senare användning medan myPage fortfarande är inom räckhåll.
Kommunicera med WPF-innehållet
Det finns två typer av kommunikation med WPF-innehållet. Programmet tar emot information från WPF-innehållet när användaren klickar på OK - eller Avbryt-knapparna . Programmet har också ett användargränssnitt som gör att användaren kan ändra olika WPF-innehållsegenskaper, till exempel bakgrundsfärg eller standardstorlek för teckensnitt.
Som nämnts ovan skapar WPF-innehållet en OnButtonClicked händelse när användaren klickar på någon av knapparna. Programmet kopplar en hanterare till den här händelsen för att ta emot dessa meddelanden. Om ok-knappen klickades hämtar hanteraren användarinformationen från WPF-innehållet och visar den i en uppsättning statiska kontroller.
void WPFButtonClicked(Object ^sender, MyPageEventArgs ^args)
{
    if(args->IsOK) //display data if OK button was clicked
    {
        WPFPage ^myPage = WPFPageHost::hostedPage;
        LPCWSTR userName = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Name: " + myPage->EnteredName).ToPointer();
        SetWindowText(nameLabel, userName);
        LPCWSTR userAddress = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Address: " + myPage->EnteredAddress).ToPointer();
        SetWindowText(addressLabel, userAddress);
        LPCWSTR userCity = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("City: " + myPage->EnteredCity).ToPointer();
        SetWindowText(cityLabel, userCity);
        LPCWSTR userState = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("State: " + myPage->EnteredState).ToPointer();
        SetWindowText(stateLabel, userState);
        LPCWSTR userZip = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Zip: " + myPage->EnteredZip).ToPointer();
        SetWindowText(zipLabel, userZip);
    }
    else
    {
        SetWindowText(nameLabel, L"Name: ");
        SetWindowText(addressLabel, L"Address: ");
        SetWindowText(cityLabel, L"City: ");
        SetWindowText(stateLabel, L"State: ");
        SetWindowText(zipLabel, L"Zip: ");
    }
}
Hanteraren tar emot ett anpassat händelseargumentobjekt från WPF-innehållet, MyPageEventArgs. Objektets IsOK egenskap är inställd på true om OK-knappen klickades och false om knappen Avbryt klickades.
Om ok-knappen klickades hämtar hanteraren en referens till WPF-innehållet från containerklassen. Den samlar sedan in användarinformationen som lagras av de associerade WPF-innehållsegenskaperna och använder de statiska kontrollerna för att visa informationen i det överordnade fönstret. Eftersom WPF-innehållsdata är i form av en hanterad sträng måste de konverteras för användning av en Win32-kontroll. Om knappen Avbryt klickades rensar hanteraren data från de statiska kontrollerna.
Programgränssnittet innehåller en uppsättning alternativknappar som gör att användaren kan ändra bakgrundsfärgen för WPF-innehållet och flera teckensnittsrelaterade egenskaper. Följande exempel är ett utdrag från programmets fönsterprocedur (WndProc) och dess meddelandehantering som anger olika egenskaper för olika meddelanden, inklusive bakgrundsfärgen. De andra är liknande och visas inte. Mer information och kontext finns i det fullständiga exemplet.
case WM_COMMAND:
  wmId    = LOWORD(wParam);
  wmEvent = HIWORD(wParam);
  switch (wmId)
  {
  //Menu selections
    case IDM_ABOUT:
      DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    break;
    case IDM_EXIT:
      DestroyWindow(hWnd);
    break;
    //RadioButtons
    case IDC_ORIGINALBACKGROUND :
      WPFPageHost::hostedPage->Background = WPFPageHost::initBackBrush;
    break;
    case IDC_LIGHTGREENBACKGROUND :
      WPFPageHost::hostedPage->Background = gcnew SolidColorBrush(Colors::LightGreen);
    break;
    case IDC_LIGHTSALMONBACKGROUND :
      WPFPageHost::hostedPage->Background = gcnew SolidColorBrush(Colors::LightSalmon);
    break;
Om du vill ange bakgrundsfärgen hämtar du en referens till WPF-innehållet (hostedPage) från WPFPageHost och anger egenskapen bakgrundsfärg till rätt färg. Exemplet använder tre färgalternativ: den ursprungliga färgen, ljusgrön eller ljus lax. Den ursprungliga bakgrundsfärgen lagras som ett statiskt fält i WPFPageHost klassen. Om du vill ange de andra två skapar du ett nytt SolidColorBrush objekt och skickar konstruktorn ett statiskt färgvärde från Colors objektet.
Implementering av WPF-sidan
Du kan vara värd för och använda WPF-innehållet utan att känna till den faktiska implementeringen. Om WPF-innehållet hade paketerats i en separat DLL kunde det ha skapats på valfritt CLR-språk (Common Language Runtime). Nedan följer en kort genomgång av C++/CLI-implementeringen som används i exemplet. Det här avsnittet innehåller följande underavsnitt.
Utformning
Gränssnittselementen i WPF-innehållet består av fem TextBox kontroller med associerade Label kontroller: Namn, Adress, Stad, Delstat och Zip. Det finns också två Button kontroller, OK och Avbryt
WPF-innehållet implementeras i WPFPage klassen . Layouten hanteras med ett Grid layoutelement. Klassen ärver från Grid, vilket i praktiken gör den till WPF-innehållsrotelementet.
WPF-innehållskonstruktorn tar den angivna bredden och höjden, och anpassar storleken på Grid därefter. Den definierar sedan den grundläggande layouten genom att skapa en uppsättning ColumnDefinition objekt och RowDefinition objekt och lägga till dem i objektbasen GridColumnDefinitionsRowDefinitions respektive samlingar. Detta definierar ett rutnät med fem rader och sju kolumner, med de dimensioner som bestäms av innehållet i cellerna.
WPFPage::WPFPage(int allottedWidth, int allotedHeight)
{
  array<ColumnDefinition ^> ^ columnDef = gcnew array<ColumnDefinition ^> (4);
  array<RowDefinition ^> ^ rowDef = gcnew array<RowDefinition ^> (6);
  this->Height = allotedHeight;
  this->Width = allottedWidth;
  this->Background = gcnew SolidColorBrush(Colors::LightGray);
  
  //Set up the Grid's row and column definitions
  for(int i=0; i<4; i++)
  {
    columnDef[i] = gcnew ColumnDefinition();
    columnDef[i]->Width = GridLength(1, GridUnitType::Auto);
    this->ColumnDefinitions->Add(columnDef[i]);
  }
  for(int i=0; i<6; i++)
  {
    rowDef[i] = gcnew RowDefinition();
    rowDef[i]->Height = GridLength(1, GridUnitType::Auto);
    this->RowDefinitions->Add(rowDef[i]);
  }
Sedan lägger konstruktorn till gränssnittselementen i Grid. Det första elementet är rubriktexten, som är en Label kontroll som är centrerad på den första raden i rutnätet.
//Add the title
titleText = gcnew Label();
titleText->Content = "Simple WPF Control";
titleText->HorizontalAlignment = System::Windows::HorizontalAlignment::Center;
titleText->Margin = Thickness(10, 5, 10, 0);
titleText->FontWeight = FontWeights::Bold;
titleText->FontSize = 14;
Grid::SetColumn(titleText, 0);
Grid::SetRow(titleText, 0);
Grid::SetColumnSpan(titleText, 4);
this->Children->Add(titleText);
Nästa rad innehåller kontrollen Namn Label och dess associerade TextBox kontroll. Eftersom samma kod används för varje etikett/textbox-par placeras den i ett par privata metoder och används för alla fem etikett-/textbox-par. Metoderna skapar lämplig kontroll och anropar Grid klassens statiska SetColumn och SetRow metoder för att placera kontrollerna i lämplig cell. När kontrollen har skapats anropar exemplet Add-metoden på Children-egenskapen av Grid för att lägga till kontrollen i rutnätet. Koden för att lägga till återstående etikett/textbox-par är liknande. Mer information finns i exempelkoden.
//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);
Implementeringen av de två metoderna är följande:
Label ^WPFPage::CreateLabel(int column, int row, String ^ text)
{
  Label ^ newLabel = gcnew Label();
  newLabel->Content = text;
  newLabel->Margin = Thickness(10, 5, 10, 0);
  newLabel->FontWeight = FontWeights::Normal;
  newLabel->FontSize = 12;
  Grid::SetColumn(newLabel, column);
  Grid::SetRow(newLabel, row);
  return newLabel;
}
TextBox ^WPFPage::CreateTextBox(int column, int row, int span)
{
  TextBox ^newTextBox = gcnew TextBox();
  newTextBox->Margin = Thickness(10, 5, 10, 0);
  Grid::SetColumn(newTextBox, column);
  Grid::SetRow(newTextBox, row);
  Grid::SetColumnSpan(newTextBox, span);
  return newTextBox;
}
Slutligen lägger exemplet till knapparna OK och Avbryt och kopplar en händelsehanterare till deras Click händelser.
//Add the Buttons and atttach event handlers
okButton = CreateButton(0, 5, "OK");
cancelButton = CreateButton(1, 5, "Cancel");
this->Children->Add(okButton);
this->Children->Add(cancelButton);
okButton->Click += gcnew RoutedEventHandler(this, &WPFPage::ButtonClicked);
cancelButton->Click += gcnew RoutedEventHandler(this, &WPFPage::ButtonClicked);
Returnera data till värdfönstret
När någon av knapparna klickas aktiveras händelsen Click . Värdfönstret kan helt enkelt koppla hanterare till dessa händelser och hämta data direkt från TextBox kontrollerna. Exemplet använder en något mindre direkt metod. Den hanterar Click wpf-innehållet och skapar sedan en anpassad händelse OnButtonClickedför att meddela WPF-innehållet. Detta gör att WPF-innehållet kan utföra viss parameterverifiering innan värden meddelas. Hanteraren hämtar texten från TextBox-kontrollerna och tilldelar den till publika egenskaper, från vilka värden kan hämta informationen.
Deklarationen för händelsen, i WPFPage.h:
public:
  delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
  WPFPage();
  WPFPage(int height, int width);
  event ButtonClickHandler ^OnButtonClicked;
Händelsehanteraren Click i WPFPage.cpp:
void WPFPage::ButtonClicked(Object ^sender, RoutedEventArgs ^args)
{
  //TODO: validate input data
  bool okClicked = true;
  if(sender == cancelButton)
    okClicked = false;
  EnteredName = nameTextBox->Text;
  EnteredAddress = addressTextBox->Text;
  EnteredCity = cityTextBox->Text;
  EnteredState = stateTextBox->Text;
  EnteredZip = zipTextBox->Text;
  OnButtonClicked(this, gcnew MyPageEventArgs(okClicked));
}
Ange WPF-egenskaper
Med Win32-värden kan användaren ändra flera WPF-innehållsegenskaper. Från Win32-sidan handlar det helt enkelt om att ändra egenskaperna. Implementeringen i WPF-innehållsklassen är något mer komplicerad eftersom det inte finns någon enskild global egenskap som styr teckensnitten för alla kontroller. I stället ändras lämplig egenskap för varje kontroll i egenskapernas uppsättningsåtkomster. I följande exempel visas koden för DefaultFontFamily egenskapen. Om du anger egenskapen anropas en privat metod som i sin tur anger FontFamily egenskaperna för de olika kontrollerna.
Från WPFPage.h:
property FontFamily^ DefaultFontFamily
{
  FontFamily^ get() {return _defaultFontFamily;}
  void set(FontFamily^ value) {SetFontFamily(value);}
};
Från WPFPage.cpp:
void WPFPage::SetFontFamily(FontFamily^ newFontFamily)
{
  _defaultFontFamily = newFontFamily;
  titleText->FontFamily = newFontFamily;
  nameLabel->FontFamily = newFontFamily;
  addressLabel->FontFamily = newFontFamily;
  cityLabel->FontFamily = newFontFamily;
  stateLabel->FontFamily = newFontFamily;
  zipLabel->FontFamily = newFontFamily;
}
Se även
.NET Desktop feedback