Search code examples
c#wpflistviewdatatemplateopacitymask

Rectangle.OpacityMask disappearing after removing the first object from the ObservableCollection


I have a Rectangle with an Opacity Mask, which works most of the time.

The ListView binds to an ObservableCollection. When, and only when I remove the first item from the collection, the OpacityMask seems to disappear on all items in the list.

All other controls in the ListView bind correctly, so I'm surprised that I'm having trouble with the one control in the DataTemplate that doesn't bind to anything.

I'm not sure if it is because it is a VSTO, but WPF Inspector and Snoop both crash when I try to inspect the VisualTree.

The Live Visual Tree in Visual Studio doesn't populate anything either. Again I put this down to being a VSTO.

To add to the weirdness, if I change the Visual Brush to a RadialGradientBrush it works perfectly.

<ListView Grid.Row="0" Margin="10" 
      Name="lstVariables" 
      ItemContainerStyle="{StaticResource ContainerStyle}"
      ItemsSource="{Binding VariablesList, Mode=OneWay}">
<ListView.ItemTemplate>
    <DataTemplate>
        <Grid Margin="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="180" />
                <ColumnDefinition Width="2*" />
                <ColumnDefinition Width="100" />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" 
                       Text="{Binding Name}" 
                       Margin="5,0,0,0"
                       Height="23" />
            <TextBox Grid.Column="1" Text="{Binding Value}" 
                      Controls:TextBoxHelper.ClearTextButton="True"
                      Height="23"
                      Width="300" />
            <Button Grid.Column="2"
                Width="100" Height="100" >
                <Rectangle Height="100" Width="100" Fill="Black" >
                    <Rectangle.OpacityMask>
                        <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_delete}" />
                    </Rectangle.OpacityMask>
                </Rectangle>
            </Button>
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>
</ListView>

Example of normal behaviour Example of normal behaviour

After removing the first item in the ObservableCollection After removing the first item in the ObservableCollection


Solution

  • VisualBrush is usually used to copy the appearance of an element in a window to a region somewhere else in that same window. In your case, only the first item initialized an object of appbar_delete and copied its appearance. The other items just copied the appearance from the same object. When you delete the first item, the only object was deleted. All items can't find the appearance then.