locked
Opacity override in ListView RRS feed

  • Question

  • Hi, 

    I am trying to implement functionality where if the user checks a checkbox of an item in a ListView, that item becomes "greyed out" (opacity changed to 50%). 

    I used to have this going in Windows 8.0, however it seems in 8.1 the opacity is being overridden back to 100% when the mouse pointer travels to another item. 

    I've changed the code to use the new Behaviors SDK, however it has the same problem. I will post that version however as it's less code to paste. Do you know what I would need to do in order to acheive this? 

    Thanks,
    Hamish

    <Page
        x:Class="PointerOver.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:PointerOver"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
        xmlns:core="using:Microsoft.Xaml.Interactions.Core"
        mc:Ignorable="d">
        <Page.Resources>
            <local:FruitList x:Name="FruitList"></local:FruitList>
        </Page.Resources>
        
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <ListView HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{StaticResource FruitList}" SelectionMode="None">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <interactivity:Interaction.Behaviors>
                                <core:DataTriggerBehavior Binding="{Binding ElementName=CheckBox, Path=IsChecked}" Value="True">
                                    <core:ChangePropertyAction PropertyName="Opacity" Value="0.5"></core:ChangePropertyAction>
                                </core:DataTriggerBehavior>
                            </interactivity:Interaction.Behaviors>
                            <CheckBox x:Name="CheckBox"></CheckBox>
                            <TextBlock Text="{Binding}"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </Page>

        public class FruitList : List<string>
        {
            public FruitList()
            {
                Add("Apple");
                Add("Orange");
                Add("Banana");
            }
             
        }


    • Edited by HamishG Sunday, November 17, 2013 12:02 PM
    Sunday, November 17, 2013 11:56 AM

Answers

  • Hi HanishG,

    I'm not familiar with Behaviors SDK, but I just got a question after I read your code.

    Here you set a "core:DataTriggerBehavior" in your DataTemplate and binding with a item(CheckBox) also in DataTemplate, let's say if you have several ListViewItems(in your case there are three), how could you identify which checkbox is the one that binding to your "core:DataTriggerBehavior".

    If you put the code outside the DataTemplate it should works fine. I can pretty sure that the issue is related the DataTemplate you are using.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Tuesday, November 19, 2013 9:20 AM
    Moderator

All replies

  • Hi HanishG,

    I'm not familiar with Behaviors SDK, but I just got a question after I read your code.

    Here you set a "core:DataTriggerBehavior" in your DataTemplate and binding with a item(CheckBox) also in DataTemplate, let's say if you have several ListViewItems(in your case there are three), how could you identify which checkbox is the one that binding to your "core:DataTriggerBehavior".

    If you put the code outside the DataTemplate it should works fine. I can pretty sure that the issue is related the DataTemplate you are using.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Tuesday, November 19, 2013 9:20 AM
    Moderator
  • Hi - I'm pretty sure it's fine to refer to a named element within a repeated DataTemplate like that, the xaml engine will figure out the one you are referring to, however, agree that this adds unneccessary complexity to show this example. 

    I have re-written it to be based on standard view models - and also setup a two way binding on the Opacity property. If you debug, you will see that the Opacity setter is set to 1.0 every time you hover over the element, it is this that is causing the Opacity to be overriden. Obviously there is some MouseOver state somewhere setting the Opacity back to 1.0, but there must be some way to work around or override this behavior? It was quite hard / impossible to find when I started modifying the control template's etc of the ListView unless I am missing something. 

        

    <Page
        x:Class="PointerOver.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:PointerOver"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Resources>
            <local:FruitList x:Name="FruitList"></local:FruitList>
            <DataTemplate x:Key="ItemTemplate">
                <Grid Background="#C400202C" x:Name="Grid" Width="100" Opacity="{Binding Opacity, Mode=TwoWay}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"></CheckBox>
                    <TextBlock Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center"></TextBlock>
                </Grid>
            </DataTemplate>
        </Page.Resources>

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <ListView 
                HorizontalAlignment="Center" 
                VerticalAlignment="Center" 
                ItemsSource="{StaticResource FruitList}" 
                SelectionMode="None"
                ItemTemplate="{StaticResource ItemTemplate}">
            </ListView>
        </Grid>
    </Page>

        public class FruitList : List<FruitListViewModel>
        {
            public FruitList()
            {
                Add(new FruitListViewModel() {Name = "Apple"});
                Add(new FruitListViewModel() { Name = "Orange" });
                Add(new FruitListViewModel() { Name = "Banana" });
            }
        }
    }

    public class FruitListViewModel : INotifyPropertyChanged
        {
            private double _opacity;
            private bool _isChecked;
            public string Name { get; set; }

            public bool IsChecked
            {
                get { return _isChecked; }
                set
                {
                    _isChecked = value;
                    if (_isChecked)
                    {
                        Opacity = 0.5;
                    }
                    else
                    {
                        Opacity = 1.0;
                    }
                }
            }

            public double Opacity
            {
                get { return _opacity; }
                set
                {
                    //This is being set to 1.0 on mouse over of the ListView items
                    _opacity = value; 
                    OnPropertyChanged();
                }
            }


            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    • Proposed as answer by NHehn Monday, February 3, 2014 8:21 PM
    • Unproposed as answer by NHehn Monday, February 3, 2014 8:21 PM
    Saturday, November 23, 2013 10:18 AM
  • I did this all as you did but instead of trying to get the Checkbox to change the grid opacity I made my stack panel that all my checkbox and all my text live in change its Opacity, and that worked like a charm, and is not bothered by the mouse over.

    <DataTemplate x:Key="ItemTemplate">
                <Grid Background="#C400202C" x:Name="Grid" Width="100" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>

                <StackPanel Opacity="{Binding Opacity, Mode=TwoWay}">

                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"></CheckBox>
                    <TextBlock Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center"></TextBlock>

                <StackPanel/>

                </Grid>
            </DataTemplate>

    This works great!


    • Proposed as answer by NHehn Monday, February 3, 2014 8:29 PM
    • Edited by NHehn Monday, February 3, 2014 8:36 PM for got one point
    • Unproposed as answer by NHehn Tuesday, February 4, 2014 10:32 PM
    Monday, February 3, 2014 8:29 PM
  • I did this all as you did but instead of trying to get the Checkbox to change the grid opacity I made my stack panel that all my checkbox and all my text live in change its Opacity, and that worked like a charm, and is not bothered by the mouse over.

    <DataTemplate x:Key="ItemTemplate">
                <Grid Background="#C400202C" x:Name="Grid" Width="100" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>

                <StackPanel Opacity="{Binding Opacity, Mode=TwoWay}">

                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"></CheckBox>
                    <TextBlock Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center"></TextBlock>

                <StackPanel/>

                </Grid>
            </DataTemplate>

    This works great!


    This worked for me till I tried to add a new item to the ListView, when I did it will not show the text on the textbox's till I checked the checkbox.  Any one have more help on this?  I would like it to show the text after I hit the add button and then be able to check the checkbox if I wanted to.

    Thanks!

    Tuesday, February 4, 2014 10:35 PM
  • Strangely - in the end I was able to solve this problem by wrapping the Grid in the ItemTemplate into a Border and it works fine! 
    Saturday, February 8, 2014 3:03 PM