What is the difference between null and transparen

2019-09-19 01:35发布

问题:

For example we have a Border. What the difference beetween these XAMLs?

1) Background="Transparent"

<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Grid
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Border
        BorderBrush="White"
        BorderThickness="2"
        Width="400"
        Height="400"
        Background="Transparent"
        PointerPressed="Border_PointerPressed"
        PointerReleased="Border_PointerReleased" />
</Grid>


2) Background="{x:Null}"

<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Grid
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Border
        BorderBrush="White"
        BorderThickness="2"
        Width="400"
        Height="400"
        Background="{x:Null}"
        PointerPressed="Border_PointerPressed"
        PointerReleased="Border_PointerReleased" />
</Grid>

Both of these borders looks identical. But what the difference?

回答1:

The difference is if we set null background the Border will not support hit-testing, that's why routed events like PonterPressed will not be raised.

Conversely though, if we set Transparent background events will be raised.

To illustrate this let's write code-behind.

using Windows.UI.Xaml.Media;

namespace App1 {
    public sealed partial class MainPage : Page {
        public MainPage() {
            this.InitializeComponent();
        }

        void Border_PointerPressed(object sender, PointerRoutedEventArgs e) {
            Border border = sender as Border;
            if (border != null)
                border.Background = new SolidColorBrush(Colors.Red);
        }
        void Border_PointerReleased(object sender, PointerRoutedEventArgs e) {
            Border border = sender as Border;
            if (border != null)
                border.Background = new SolidColorBrush(Colors.Transparent);
        }
    }
}

1) Let's use the first XAML, compile our app and run it. Try to tap inside the square. The square becomes red because the events are rised and the handlers calls.

2) Now let's use the second XAML, compile the app, run it, tap inside the square. Nothing happens because the events are not rised. The handlers are not calls.



回答2:

For completeness, I found this link http://msdn.microsoft.com/en-us/library/hh758286.aspx#hit_testing explaining this rather well - see especially the second bullet point:

Hit testing and input events

Determining whether and where in UI an element is visible to mouse, touch, and stylus input is called hit testing. For touch actions and also for interaction-specific or manipulation events that are consequences of a touch action, an element must be hit-test visible in order to be the event source and fire the event that is associated with the action. Otherwise, the action passes through the element to any underlying elements or parent elements in the visual tree that could interact with that input. There are several factors that affect hit testing, but you can determine whether a given element can fire input events by checking its IsHitTestVisible property. This property returns true only if the element meets these criteria:

  • The element's Visibility property value is Visible.
  • The element's Background or Fill property value is not null. A null Brush value results in transparency and hit test invisibility. (To make an element transparent but also hit testable, use a Transparent brush instead of null.) Note Background and Fill aren't defined by UIElement, and are instead defined by different derived classes such as Control and Shape. But the implications of brushes you use for foreground and background properties are the same for hit testing and input events, no matter which subclass implements the properties.
  • If the element is a control, its IsEnabled property value must be true.
  • The element must have actual dimensions in layout. An element where either ActualHeight and ActualWidth are 0 won't fire input events.