fix(controls): Fix TextBlock style, typography and related issues#1631
fix(controls): Fix TextBlock style, typography and related issues#1631apachezy wants to merge 3 commits intolepoco:mainfrom
Conversation
|
This PR has uncovered a new issue: when a I suspect that property scanning or reading certain information incorrectly triggers a re‑layout. This behavior may be related to a flaw in the dependency‑property system’s handling of default‑value “application” or “coercion” logic under specific triggering conditions (such as property queries, layout passes, or visual‑tree state updates) for inherited controls. I’m converting this PR to draft. Please do not merge it until the root cause is understood and resolved. |
249016a to
fa669cc
Compare
|
Resolved — reopening this PR. The reason this PR was previously marked as Draft was a layout size fluctuation observed at design time. After further investigation, this issue was identified as originating from a behavioral issue in the native WPF TextBlock. When certain rich-text-related properties are accessed (such as ContentStart and ContentEnd, which commonly happens when designers or property inspectors enumerate properties), TextBlock may be unconditionally forced into ComplexContent mode. This becomes observable under the following combination of conditions:
The result is a visible issue where the font size appears to “revert” to a smaller value when the control is inspected or selected at design time. The resolution is based on two key observations:
Therefore, this fix aligns the default FontSize of TextElement with the Fluent design by setting it to 14. Based on this, the PR has been restored to an open, reviewable state. |
389fb07 to
933964f
Compare
1b073fa to
e7a0fbe
Compare
e7a0fbe to
a5c932c
Compare
|
This comment is directed to you as the repository owner. I want to provide some additional context on the design choices and implementation details of this PR for your awareness:
The PR aims to address multiple issues while maintaining WPF best practices, including dependency property inheritance, dynamic theming, and high-frequency control performance. I respect the review process and understand decisions are ultimately up to the assigned reviewer, but I wanted to ensure the rationale and constraints behind this design are clear for your awareness. |
|
I’d like to add a short clarification in case the intent of this PR is not fully clear, especially regarding the discussion around Styles vs presets. 1. Preset vs. “FontTypographyStyle” (style-based approach)If we assume an alternative design where an attached property like a) Read values from a Style and apply them to the TextBlock
b) Apply the Style directly to the TextBlock
This is why 2. TryFindResource vs. proxy (attached) propertiesRegarding the discussion about
This distinction is important in the context of 3. Foreground resolutionThe foreground resolution logic is intentionally designed to balance theme safety, inheritance behavior, and predictable fallbacks. While this results in a multi-step pipeline, the goal is to ensure correctness under dynamic theming rather than to introduce additional complexity. If a simpler approach is preferred, this can be revisited separately. 4. Overall design intentMore broadly, the design choices in this PR are guided by a few core principles:
These decisions may trade some surface-level convenience for clarity, correctness, and long-term maintainability. If you feel that this design is overly complex, too indirect, or simply not aligned with the direction of the library, I fully understand and accept that judgment. My intent here is to clearly document the reasoning behind the approach, even if a different trade-off is ultimately preferred. Thank you for taking the time to read this clarification. |
|
唉,即使经过AI工具和翻译器我也很难表达出我的设计意图和理解讨论内容。 |
|
Closing in favor of #1640 |
Pull request type
Please check the type of change your PR introduces:
What is the current behavior?
The current TextBlock implementation suffers from several design flaws and functional issues:
1. Implicit Style System Broken
Incorrect Constructor Logic: PR (Fix Wpf.Ui.Controls.TextBlock default style #1347) forcibly applied SetResourceReference(StyleProperty, defaultFontTypography.ToResourceValue()) in the constructor, setting a high-priority style reference that completely disabled implicit styling (including locally defined implicit styles).
Improper Style Resource Definitions: The FontTypography resources predefined in Typography.xaml were typed as Style. When applied to TextBlock, they would replace the entire control's style—not just typography properties—causing the loss of foreground, background, alignment, and other style attributes (including the control template).
2. Confused Property Priority
FontTypography vs. Native Property Conflicts: When both FontTypography and native properties like FontSize or FontWeight were set together, the order of effect depended on the declaration order in XAML, rather than the intended design logic.
Example:
FontSize="36"applied firstFontTypography="Subtitle"overrode the font size to 20FontWeight="Normal"then overrode Subtitle's SemiBoldFinal result: FontSize=20, FontWeight=Normal—contrary to expectation.
3. Design Pattern Inconsistencies with WPF Conventions
Enums as Property Type: The FontTypography and Appearance properties used enums instead of static resource classes (like WPF’s FontWeights, Brushes), requiring a resource lookup on every property change and incurring unnecessary performance overhead.
Vertical Alignment Issues: Issue The title is not aligned. #1617 and the closed PR fix(controls): Resolve vertical alignment issue in WPFUI TextBlock #1624 highlighted abnormal vertical alignment in TextBlock.
Redundant Style Settings: TextBlock.xaml contained redundant and harmful style properties that interfered with the control's normal behavior.
Issue Number: #920 #1617 #1459 #1248 #887 #908 #890
What is the new behavior?
This fix refactors the TextBlock implementation, preserving WPF’s native characteristics while ensuring WPFUI-specific features work correctly.
1. Restore WPF Native Styling System
Remove Destructive Code: Delete the SetResourceReference call in the constructor and any logic that bypassed style priority rules.
Clean Up Redundant Styles: Simplify TextBlock.xaml, keeping only necessary property settings, so that native TextBlock behaves correctly while retaining WPFUI’s theme styling.
2. Redesign the Typography System
Introduce FontTypographyPreset Class: A lightweight typography preset class containing properties like FontSize and FontWeight, replacing full Style resources.
Refactor Resource Definitions: Update Typography.xaml to define typography presets using FontTypographyPreset and adjust resource key names for clarity.
Update Enum Mapping: Adjust the enum mapping in TextBlockFontTypographyExtensions to align with the new resource definitions.
3. Clear Property Priority Rules
Nullable-Type Design: Change FontTypography and Appearance to nullable types (Nullable) to clearly distinguish between “set” and “unset” states.
Priority Logic:
When FontTypography or Appearance is set and its internal property (e.g., FontSize) is not null, use the preset value.
When these properties are unset or their internal property is null, fall back to the native property value.
Preset properties have higher priority than native properties, but only when explicitly set.
4. Native TextBlock Control Compatibility
This represents a design trade-off: while native WPF controls should, in principle, retain their default behavior, one of WPFUI’s design goals is to allow native controls to adopt the Fluent design style.
To achieve this, the following mechanisms have been introduced:
TextBlockMetadataInitializer: Overrides the dependency property metadata of the native TextBlock during library initialization, enabling it to use WPFUI-defined defaults (such as font size and theme‑responsive foreground colors) while still allowing further customization at the application level.
TextBlockHelper: Provides a default foreground color for native TextBlock via an attached property. When the foreground is not explicitly set, the current theme’s TextFillColorPrimaryBrush is automatically applied, ensuring text colors remain consistent with the Fluent theme.
Automatic Initialization Integration: Calls TextBlockMetadataInitializer.EnsureInitialized() in the ControlsDictionary constructor, guaranteeing that when this resource dictionary is referenced by the application (typically in App.xaml), the native TextBlock metadata is overridden promptly, without requiring extra initialization by developers.
This design maintains compatibility with native controls while providing a smooth migration path for scenarios that wish to apply the Fluent style globally.
5. Fix Known Issues
Fixed Remove all FontSize setting from the global style ? #920
Fixed The title is not aligned. #1617
LineHeightproperty: Resolves the vertical-center alignment issues caused by explicitly settingLineHeight.Fixed In WPF-UI version 4.0.3, it is no longer possible to override global control styles (e.g., TextBlock.FontSize) from App.xaml using implicit styles #1459
Fixed Font size identical for Body and Caption FontTypographies #1248
Related Style‑System Issues (Inheritance & Priority Fixes)
Fixed Button FontSize ineffective #887
Fixed Menu Font size not changing #908
Fixed Unable to Set Font Size for ComboBox and Butten #890
These issues all stemmed from violations of WPF’s inheritance mechanism or dependency‑property priority rules and have been uniformly resolved in this refactoring. These issues will be automatically closed when this PR is merged.
6. Backward Compatibility
API Unchanged: The public interface of FontTypography and Appearance properties remains the same.
Default Behavior Preserved: The native TextBlock default style still matches the WPFUI‑predefined “Body” font size and correctly applies WPFUI theme colors.
Performance Improvements: Reduced unnecessary resource lookups, improving performance during property changes.
Other information
This fix restores TextBlock’s compliance with WPF’s dependency‑property priority system, resolving core problems such as implicit‑style failure, property conflicts, and vertical‑alignment issues. The new implementation retains WPFUI’s design identity while ensuring consistency with native WPF development patterns, making the control more stable and easier to use.