platform-config-sample.xml 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Enhanced Platform-specific UI Layout Definition v1.5 -->
  3. <ui-layout-def xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns="ui-layout-definition"
  5. xsi:schemaLocation="ui-layout-definition ui-layout-def.xsd"
  6. version="1.5"
  7. schema-version="1.6"
  8. min-version="1.0"
  9. max-version="2.0"
  10. target-platform="avalonia"
  11. accessibility-compliance="wcag-aa">
  12. <!-- Enhanced validation rules with custom validators -->
  13. <validation-rules>
  14. <validation-include src="wcag-validation.xml" important="true" min-version="1.3" />
  15. <validation-include src="avalonia-validation.xml" important="true" platform="avalonia" />
  16. <validation-include src="performance-validation.xml" important="false" min-version="1.3" />
  17. <custom-validator name="PlatformCompatibilityValidator" version="1.0" category="compatibility">
  18. <description>Validates platform-specific control usage</description>
  19. <implementation>
  20. <script language="javascript">
  21. function validate(element, context) {
  22. const platform = context.targetPlatform;
  23. const controlPlatform = element.getAttribute('platform-hint') || 'basic';
  24. return platform === controlPlatform || controlPlatform === 'basic';
  25. }
  26. </script>
  27. </implementation>
  28. </custom-validator>
  29. <validation-profile name="AvaloniaProductionProfile" target-platform="avalonia" enabled="true">
  30. <description>Production validation profile for Avalonia applications</description>
  31. <profile-rule rule-name="PlatformCompatibilityValidator" enabled="true" severity="warning" />
  32. <profile-rule rule-name="accessibility-compliance" enabled="true" severity="error" />
  33. <configuration parallel-execution="true" cache-results="true">
  34. <setting key="min-avalonia-version" value="11.0" scope="profile" />
  35. </configuration>
  36. </validation-profile>
  37. </validation-rules>
  38. <!-- Platform-specific patterns with version constraints -->
  39. <patterns>
  40. <!-- Core Avalonia controls -->
  41. <pattern-include src="avalonia-controls.xml" important="true" platform="avalonia" min-version="1.3" />
  42. <!-- Enhanced accessibility controls -->
  43. <pattern-include src="accessibility-controls.xml" important="true" min-version="1.3" />
  44. <!-- Performance-optimized controls -->
  45. <pattern-include src="performance-controls.xml" important="false" min-version="1.3" />
  46. <!-- Platform-specific enhanced control -->
  47. <control name="AvaloniaEnhancedDataGrid" type="data" category="avalonia-data" schema-version="1.6">
  48. <description>Avalonia-specific data grid with advanced features</description>
  49. <constraints>
  50. <allowed-parents>Panel,Grid,ScrollViewer</allowed-parents>
  51. <allowed-children>columns</allowed-children>
  52. <container>true</container>
  53. <platform-constraints>
  54. <platform-constraint platform="avalonia" min-version="11.0"
  55. feature-required="data-virtualization" />
  56. </platform-constraints>
  57. <performance-hints virtualization-supported="true" heavy-rendering="false"
  58. recommended-max-items="50000" />
  59. </constraints>
  60. <attributes>
  61. <attribute name="items-source" type="binding" category="data"
  62. description="Collection binding for data source" />
  63. <attribute name="virtualization-mode" type="enum"
  64. values="None,Standard,Recycling" default="Recycling"
  65. category="performance" platform-specific="avalonia" />
  66. <attribute name="theme-variant" type="enum"
  67. values="Default,Light,Dark,HighContrast" default="Default"
  68. category="appearance" platform-specific="avalonia" />
  69. </attributes>
  70. <data-binding supports-two-way="true" supports-commands="true" supports-validation="true">
  71. <bindable-property name="ItemsSource" type="collection" mode="OneWay"
  72. dependency-property="true" />
  73. <bindable-property name="SelectedItems" type="collection" mode="TwoWay"
  74. dependency-property="true" />
  75. <bindable-property name="CurrentItem" type="object" mode="TwoWay" />
  76. </data-binding>
  77. <behavior>
  78. <event name="selection-changed" async="false" accessibility-event="true" />
  79. <event name="cell-edit-ending" async="false" cancelable="true" />
  80. <command name="ExportCommand" can-execute-property="HasData" async="true" />
  81. <gesture name="double-tap-edit" type="double-tap" platform-specific="avalonia" />
  82. </behavior>
  83. </control>
  84. </patterns>
  85. <!-- Enhanced business views -->
  86. <views>
  87. <view-include src="business-views.xml" important="true" min-version="1.2" />
  88. <!-- Platform-optimized view -->
  89. <view name="AvaloniaProductManagementView" type="business-entity" category="core"
  90. schema-version="1.6" platform="avalonia" singleton="false" lazy-loading="true"
  91. cacheable="true" priority="high">
  92. <description>Product management optimized for Avalonia UI</description>
  93. <metadata>
  94. <model-class>Product</model-class>
  95. <view-model-class>AvaloniaProductViewModel</view-model-class>
  96. <permissions>product.read,product.write</permissions>
  97. <author>Platform Team</author>
  98. <version>2.1.0</version>
  99. <documentation-url>https://docs.company.com/avalonia-product-view</documentation-url>
  100. <tags>
  101. <tag>avalonia-optimized</tag>
  102. <tag>high-performance</tag>
  103. <tag>accessible</tag>
  104. </tags>
  105. </metadata>
  106. <!-- Avalonia-specific state management -->
  107. <state-management pattern="redux" persistence="local">
  108. <state name="initializing" initial="true" data-snapshot="InitState" />
  109. <state name="loaded" final="false" data-snapshot="LoadedState" />
  110. <state name="editing" final="false" data-snapshot="EditState" />
  111. <state name="saving" final="false" data-snapshot="SavingState" />
  112. <transition from="initializing" to="loaded" trigger="data-loaded"
  113. condition="products.length > 0" action="displayProducts" />
  114. <transition from="loaded" to="editing" trigger="edit-requested" action="startEdit" />
  115. <transition from="editing" to="saving" trigger="save-requested"
  116. condition="validation.isValid" action="saveProduct" />
  117. <transition from="saving" to="loaded" trigger="save-completed" action="refreshView" />
  118. </state-management>
  119. <!-- Enhanced accessibility for Avalonia -->
  120. <accessibility level="aa" tested="true">
  121. <compliance standard="wcag" level="aa" verified="true" />
  122. <feature name="screen-reader" type="screen-reader" required="true"
  123. implementation="Avalonia accessibility tree integration" />
  124. <feature name="keyboard-navigation" type="keyboard-navigation" required="true"
  125. implementation="Full tab navigation with focus indicators" />
  126. <feature name="high-contrast" type="high-contrast" required="true"
  127. implementation="Avalonia theme system integration" />
  128. </accessibility>
  129. <!-- Performance optimization for large datasets -->
  130. <performance target-load-time="800" memory-limit="200MB">
  131. <metric name="grid-render-time" type="load-time" target="300ms" critical="true" />
  132. <metric name="scroll-performance" type="frame-rate" target="60fps" critical="true" />
  133. <optimization technique="virtualization" description="UI virtualization for product grid" impact="high" />
  134. <optimization technique="lazy-loading" description="Load product details on demand" impact="medium" />
  135. <optimization technique="caching" description="Cache frequently accessed products" impact="medium" />
  136. </performance>
  137. <!-- Enhanced security -->
  138. <security level="high" audit-required="true">
  139. <permission name="product-read" type="read" required="true" scope="view" />
  140. <permission name="product-write" type="write" required="false" scope="data" />
  141. <vulnerability-protection type="injection" protection="parameterized-queries" severity="critical" />
  142. <data-protection encryption="true" gdpr-compliant="true" />
  143. </security>
  144. <!-- Comprehensive localization -->
  145. <localization default-culture="en-US" rtl-support="true">
  146. <supported-culture code="de-DE" name="German" completion="100" verified="true" />
  147. <supported-culture code="fr-FR" name="French" completion="95" verified="true" />
  148. <supported-culture code="ar-SA" name="Arabic" completion="80" verified="false" />
  149. <resource-bundle name="ProductResources" path="Resources/Products" type="resx" />
  150. </localization>
  151. <!-- Avalonia-specific testing -->
  152. <testing coverage-target="90" strategy="integration">
  153. <test-scenario name="product-crud" type="functional" priority="high" automated="true">
  154. <step action="load-products" expected="grid-populated" />
  155. <step action="create-product" expected="edit-dialog-shown" />
  156. <step action="save-product" expected="product-saved" />
  157. </test-scenario>
  158. <test-scenario name="accessibility-compliance" type="accessibility" priority="high" automated="true">
  159. <step action="keyboard-navigation" expected="all-controls-accessible" />
  160. <step action="screen-reader-test" expected="proper-announcements" />
  161. </test-scenario>
  162. <automation framework="avalonia-test-framework" selector-strategy="accessibility" />
  163. </testing>
  164. <dependencies>
  165. <service-ref name="ProductService" interface="IProductService" scope="scoped" required="true" />
  166. <library-ref name="Avalonia.Controls.DataGrid" version="11.0.0" source="nuget" optional="false" />
  167. </dependencies>
  168. <data-context>
  169. <property name="products" type="ObservableCollection&lt;Product&gt;" scope="view"
  170. observable="true" validation="NotNull" />
  171. <property name="selectedProduct" type="Product" scope="view" nullable="true" observable="true" />
  172. <property name="isLoading" type="bool" scope="view" default-value="false" observable="true" />
  173. <property name="filterText" type="string" scope="view" default-value="" observable="true" />
  174. </data-context>
  175. <windows>
  176. <window-ref name="ProductListWindow" role="main" default="true" lazy-load="false"
  177. priority="critical" />
  178. <window-ref name="ProductEditDialog" role="editor" default="false" lazy-load="true"
  179. priority="normal" />
  180. </windows>
  181. <communication>
  182. <publishes>
  183. <event name="product-selected" data="product-id" async="false" />
  184. <event name="products-filtered" data="filter-criteria" async="true" />
  185. </publishes>
  186. <subscribes>
  187. <event name="product-updated" source="ProductService" handler="refresh-product"
  188. async="true" debounce="1000" />
  189. </subscribes>
  190. <real-time>
  191. <connection name="product-updates" protocol="signalr" endpoint="/productHub"
  192. auto-reconnect="true" />
  193. </real-time>
  194. </communication>
  195. </view>
  196. </views>
  197. <!-- Platform-specific window includes -->
  198. <window-includes>
  199. <window-include src="avalonia-windows.xml" important="true" platform="avalonia" min-version="1.3" />
  200. <window-include src="responsive-windows.xml" important="false" min-version="1.3" />
  201. </window-includes>
  202. <!-- Enhanced main window with Avalonia-specific features -->
  203. <window name="ProductListWindow" title="Product Management - Avalonia"
  204. view="AvaloniaProductManagementView" target-platform="avalonia" schema-version="1.6">
  205. <attributes>
  206. <attribute name="width" value="1200" />
  207. <attribute name="height" value="800" />
  208. <attribute name="min-width" value="800" />
  209. <attribute name="min-height" value="600" />
  210. <attribute name="window-state" value="Normal" />
  211. <attribute name="can-resize" value="true" />
  212. <attribute name="system-decorations" value="Full" />
  213. <attribute name="extend-client-area-to-decorations-hint" value="false" />
  214. </attributes>
  215. <view-properties>
  216. <role>main</role>
  217. <default>true</default>
  218. <data-context-binding>products</data-context-binding>
  219. </view-properties>
  220. <!-- Enhanced data binding for Avalonia -->
  221. <data-binding>
  222. <data-context source="AvaloniaProductViewModel" type="ViewModels.AvaloniaProductViewModel" mode="TwoWay" />
  223. <view-model class="AvaloniaProductViewModel" assembly="ProductManagement.Avalonia"
  224. namespace="ProductManagement.ViewModels" />
  225. <binding-properties>
  226. <property control="productGrid" property="ItemsSource" binding-path="Products"
  227. mode="OneWay" validation-rule="NotNullValidator" />
  228. <property control="searchBox" property="Text" binding-path="FilterText"
  229. mode="TwoWay" converter="StringTrimConverter" />
  230. <property control="loadingIndicator" property="IsVisible" binding-path="IsLoading"
  231. mode="OneWay" converter="BooleanToVisibilityConverter" />
  232. </binding-properties>
  233. </data-binding>
  234. <!-- Avalonia-specific accessibility -->
  235. <accessibility compliance-level="wcag-aa">
  236. <screen-reader window-title="Product Management Application"
  237. description="Manage products with full accessibility support"
  238. landmark-role="main" />
  239. <keyboard-navigation tab-order-start="1" focus-trap="false" escape-closes="false" />
  240. <color-contrast high-contrast-support="true" minimum-ratio="4.5" />
  241. </accessibility>
  242. <!-- Main layout with Avalonia controls -->
  243. <DockPanel name="mainContainer">
  244. <!-- Header with Avalonia-specific controls -->
  245. <Border name="headerBorder" dock-panel-dock="Top" background="LightGray" padding="10">
  246. <Grid name="headerGrid">
  247. <grid-definitions>
  248. <column-definitions>
  249. <column-definition width="*" />
  250. <column-definition width="Auto" />
  251. <column-definition width="Auto" />
  252. </column-definitions>
  253. </grid-definitions>
  254. <TextBlock name="titleText" grid-column="0" text="Product Management"
  255. font-size="18" font-weight="Bold" vertical-alignment="Center"
  256. aria-label="Application title" />
  257. <ProgressBar name="loadingIndicator" grid-column="1" width="100" height="4"
  258. is-indeterminate="true" is-visible="{Binding IsLoading}"
  259. margin="10,0" vertical-alignment="Center"
  260. aria-label="Loading progress" />
  261. <StackPanel name="actionButtons" grid-column="2" orientation="horizontal" spacing="5">
  262. <Button name="addButton" content="Add Product"
  263. command="{Binding AddProductCommand}"
  264. aria-label="Add new product" />
  265. <Button name="refreshButton" content="Refresh"
  266. command="{Binding RefreshCommand}"
  267. aria-label="Refresh product list" />
  268. <Button name="settingsButton" content="Settings"
  269. command="{Binding ShowSettingsCommand}"
  270. aria-label="Open application settings" />
  271. </StackPanel>
  272. </Grid>
  273. </Border>
  274. <!-- Search and filter panel -->
  275. <Border name="filterBorder" dock-panel-dock="Top" background="WhiteSmoke" padding="10">
  276. <Grid name="filterGrid">
  277. <grid-definitions>
  278. <column-definitions>
  279. <column-definition width="Auto" />
  280. <column-definition width="*" />
  281. <column-definition width="Auto" />
  282. <column-definition width="Auto" />
  283. </column-definitions>
  284. </grid-definitions>
  285. <TextBlock name="searchLabel" grid-column="0" text="Search:"
  286. vertical-alignment="Center" margin="0,0,10,0"
  287. aria-label="Search products" />
  288. <AutoCompleteBox name="searchBox" grid-column="1"
  289. placeholder-text="Search products by name, SKU, or category..."
  290. text="{Binding FilterText, Mode=TwoWay}"
  291. items-source="{Binding SearchSuggestions}"
  292. minimum-prefix-length="2" filter-mode="Contains"
  293. aria-label="Product search field"
  294. aria-description="Enter text to search and filter products" />
  295. <ComboBox name="categoryFilter" grid-column="2"
  296. placeholder-text="All Categories"
  297. items-source="{Binding Categories}"
  298. selected-item="{Binding SelectedCategory, Mode=TwoWay}"
  299. display-member-path="Name" margin="10,0,0,0"
  300. aria-label="Filter by category" />
  301. <Button name="clearFiltersButton" grid-column="3" content="Clear"
  302. command="{Binding ClearFiltersCommand}" margin="10,0,0,0"
  303. aria-label="Clear all filters" />
  304. </Grid>
  305. </Border>
  306. <!-- Main data grid with Avalonia-specific features -->
  307. <AvaloniaEnhancedDataGrid name="productGrid"
  308. items-source="{Binding Products}"
  309. selected-item="{Binding SelectedProduct, Mode=TwoWay}"
  310. virtualization-mode="Recycling"
  311. theme-variant="{Binding CurrentTheme}"
  312. can-user-resize-columns="true"
  313. can-user-sort-columns="true"
  314. can-user-reorder-columns="true"
  315. grid-lines-visibility="Horizontal"
  316. selection-mode="Single"
  317. aria-label="Products data grid"
  318. aria-description="List of products with sorting and filtering capabilities">
  319. <AvaloniaEnhancedDataGrid.Columns>
  320. <DataGridTextColumn header="SKU" binding="{Binding SKU}" width="120"
  321. is-read-only="true" aria-label="Product SKU" />
  322. <DataGridTextColumn header="Name" binding="{Binding Name}" width="200"
  323. is-read-only="true" aria-label="Product name" />
  324. <DataGridTextColumn header="Category" binding="{Binding Category.Name}" width="150"
  325. is-read-only="true" aria-label="Product category" />
  326. <DataGridTextColumn header="Price" binding="{Binding Price}" width="100"
  327. is-read-only="true" aria-label="Product price">
  328. <DataGridTextColumn.ElementStyle>
  329. <Style TargetType="TextBlock">
  330. <Setter Property="HorizontalAlignment" Value="Right" />
  331. <Setter Property="FontWeight" Value="Bold" />
  332. </Style>
  333. </DataGridTextColumn.ElementStyle>
  334. </DataGridTextColumn>
  335. <DataGridTextColumn header="Stock" binding="{Binding StockQuantity}" width="80"
  336. is-read-only="true" aria-label="Stock quantity">
  337. <DataGridTextColumn.ElementStyle>
  338. <Style TargetType="TextBlock">
  339. <Setter Property="HorizontalAlignment" Value="Center" />
  340. </Style>
  341. </DataGridTextColumn.ElementStyle>
  342. </DataGridTextColumn>
  343. <DataGridCheckBoxColumn header="Active" binding="{Binding IsActive}" width="60"
  344. is-read-only="true" aria-label="Product status" />
  345. <DataGridTemplateColumn header="Actions" width="150" aria-label="Product actions">
  346. <DataGridTemplateColumn.CellTemplate>
  347. <DataTemplate>
  348. <StackPanel orientation="horizontal" spacing="5" horizontal-alignment="Center">
  349. <Button content="Edit" command="{Binding $parent[Window].DataContext.EditProductCommand}"
  350. command-parameter="{Binding}"
  351. classes="compact" aria-label="Edit product" />
  352. <Button content="View" command="{Binding $parent[Window].DataContext.ViewProductCommand}"
  353. command-parameter="{Binding}"
  354. classes="compact" aria-label="View product details" />
  355. <Button content="Delete" command="{Binding $parent[Window].DataContext.DeleteProductCommand}"
  356. command-parameter="{Binding}"
  357. classes="compact danger" aria-label="Delete product" />
  358. </StackPanel>
  359. </DataTemplate>
  360. </DataGridTemplateColumn.CellTemplate>
  361. </DataGridTemplateColumn>
  362. </AvaloniaEnhancedDataGrid.Columns>
  363. </AvaloniaEnhancedDataGrid>
  364. <!-- Status bar with Avalonia styling -->
  365. <Border name="statusBorder" dock-panel-dock="Bottom" background="LightGray"
  366. border-brush="Gray" border-thickness="0,1,0,0" padding="10,5">
  367. <Grid name="statusGrid">
  368. <grid-definitions>
  369. <column-definitions>
  370. <column-definition width="*" />
  371. <column-definition width="Auto" />
  372. <column-definition width="Auto" />
  373. <column-definition width="Auto" />
  374. </column-definitions>
  375. </grid-definitions>
  376. <TextBlock name="statusText" grid-column="0"
  377. text="{Binding StatusMessage}"
  378. vertical-alignment="Center"
  379. aria-live="polite" aria-label="Status information" />
  380. <TextBlock name="recordCount" grid-column="1"
  381. text="{Binding Products.Count, StringFormat='Products: {0}'}"
  382. vertical-alignment="Center" margin="10,0"
  383. aria-label="Total product count" />
  384. <TextBlock name="selectedCount" grid-column="2"
  385. text="{Binding SelectedItems.Count, StringFormat='Selected: {0}'}"
  386. vertical-alignment="Center" margin="10,0"
  387. aria-label="Selected products count" />
  388. <TextBlock name="lastUpdated" grid-column="3"
  389. text="{Binding LastUpdated, StringFormat='Updated: {0:HH:mm:ss}'}"
  390. vertical-alignment="Center" margin="10,0"
  391. aria-label="Last update time" />
  392. </Grid>
  393. </Border>
  394. </DockPanel>
  395. </window>
  396. <!-- Product edit dialog with Avalonia features -->
  397. <window name="ProductEditDialog" title="Edit Product"
  398. view="AvaloniaProductManagementView" target-platform="avalonia" schema-version="1.6">
  399. <attributes>
  400. <attribute name="width" value="500" />
  401. <attribute name="height" value="600" />
  402. <attribute name="can-resize" value="true" />
  403. <attribute name="show-in-taskbar" value="false" />
  404. <attribute name="window-startup-location" value="CenterOwner" />
  405. <attribute name="system-decorations" value="Full" />
  406. </attributes>
  407. <view-properties>
  408. <role>editor</role>
  409. <modal>true</modal>
  410. <data-context-binding>selectedProduct</data-context-binding>
  411. <parent-window>ProductListWindow</parent-window>
  412. </view-properties>
  413. <accessibility compliance-level="wcag-aa">
  414. <screen-reader window-title="Product Edit Dialog"
  415. description="Form for editing product information"
  416. landmark-role="dialog" />
  417. <keyboard-navigation tab-order-start="1" focus-trap="true" escape-closes="true" />
  418. </accessibility>
  419. <ScrollViewer name="editFormContainer" vertical-scroll-bar-visibility="Auto">
  420. <StackPanel name="editFormPanel" spacing="15" margin="20">
  421. <TextBlock text="Product Information" font-size="16" font-weight="Bold"
  422. aria-label="Product information section" />
  423. <Grid name="formGrid">
  424. <grid-definitions>
  425. <column-definitions>
  426. <column-definition width="120" />
  427. <column-definition width="*" />
  428. </column-definitions>
  429. <row-definitions>
  430. <row-definition height="Auto" />
  431. <row-definition height="Auto" />
  432. <row-definition height="Auto" />
  433. <row-definition height="Auto" />
  434. <row-definition height="Auto" />
  435. <row-definition height="Auto" />
  436. <row-definition height="Auto" />
  437. </row-definitions>
  438. </grid-definitions>
  439. <TextBlock grid-row="0" grid-column="0" text="SKU:"
  440. vertical-alignment="Center" aria-label="Product SKU" />
  441. <TextBox name="skuTextBox" grid-row="0" grid-column="1"
  442. text="{Binding SKU, Mode=TwoWay}" watermark="Enter SKU..."
  443. aria-label="Product SKU input" />
  444. <TextBlock grid-row="1" grid-column="0" text="Name:"
  445. vertical-alignment="Center" margin="0,10,0,0"
  446. aria-label="Product name" />
  447. <TextBox name="nameTextBox" grid-row="1" grid-column="1" margin="0,10,0,0"
  448. text="{Binding Name, Mode=TwoWay}" watermark="Enter product name..."
  449. aria-label="Product name input" />
  450. <TextBlock grid-row="2" grid-column="0" text="Category:"
  451. vertical-alignment="Center" margin="0,10,0,0"
  452. aria-label="Product category" />
  453. <ComboBox name="categoryComboBox" grid-row="2" grid-column="1" margin="0,10,0,0"
  454. items-source="{Binding Categories}"
  455. selected-item="{Binding Category, Mode=TwoWay}"
  456. display-member-path="Name" placeholder-text="Select category..."
  457. aria-label="Product category selection" />
  458. <TextBlock grid-row="3" grid-column="0" text="Price:"
  459. vertical-alignment="Center" margin="0,10,0,0"
  460. aria-label="Product price" />
  461. <NumericUpDown name="priceUpDown" grid-row="3" grid-column="1" margin="0,10,0,0"
  462. value="{Binding Price, Mode=TwoWay}" minimum="0" increment="0.01"
  463. format-string="C2" aria-label="Product price input" />
  464. <TextBlock grid-row="4" grid-column="0" text="Stock:"
  465. vertical-alignment="Center" margin="0,10,0,0"
  466. aria-label="Stock quantity" />
  467. <NumericUpDown name="stockUpDown" grid-row="4" grid-column="1" margin="0,10,0,0"
  468. value="{Binding StockQuantity, Mode=TwoWay}" minimum="0"
  469. aria-label="Stock quantity input" />
  470. <TextBlock grid-row="5" grid-column="0" text="Description:"
  471. vertical-alignment="Top" margin="0,10,0,0"
  472. aria-label="Product description" />
  473. <TextBox name="descriptionTextBox" grid-row="5" grid-column="1" margin="0,10,0,0"
  474. text="{Binding Description, Mode=TwoWay}"
  475. accepts-return="true" text-wrapping="Wrap" height="80"
  476. watermark="Enter product description..."
  477. aria-label="Product description input" />
  478. <CheckBox name="activeCheckBox" grid-row="6" grid-column="1" margin="0,10,0,0"
  479. content="Active" is-checked="{Binding IsActive, Mode=TwoWay}"
  480. aria-label="Product active status" />
  481. </Grid>
  482. <!-- Dialog buttons -->
  483. <StackPanel name="buttonPanel" orientation="horizontal"
  484. horizontal-alignment="Right" spacing="10" margin="0,20,0,0">
  485. <Button name="saveButton" content="Save"
  486. command="{Binding SaveProductCommand}"
  487. classes="accent" aria-label="Save product changes" />
  488. <Button name="cancelButton" content="Cancel"
  489. command="{Binding CancelEditCommand}"
  490. aria-label="Cancel without saving" />
  491. <Button name="deleteButton" content="Delete"
  492. command="{Binding DeleteProductCommand}"
  493. classes="danger" aria-label="Delete this product" />
  494. </StackPanel>
  495. </StackPanel>
  496. </ScrollViewer>
  497. </window>
  498. </ui-layout-def>