简体   繁体   中英

List box with multiple data template - style for selected item

I have List Box with 2 data template, i have a ItemContainerStyle for list box as well which will highlight the selected item in the list box.

Below is my code:

<DataTemplate x:Key="DefaultDataTemplate">
            <Border  

                    Margin="0,2,0,0" 
                    VerticalAlignment="Stretch"
                    HorizontalAlignment="Stretch">
                <Grid> items ...</Grid>
           </Border>
</DataTemplate>

Datatemplate with Convertor:

<DataTemplate x:Key="NewDataTemplate">
            <Border  
                    Background="{Binding Converter={StaticResource BackgroundConvertor}}"
                    Margin="0,2,0,0" 
                    VerticalAlignment="Stretch"
                    HorizontalAlignment="Stretch">
                <Grid> items ...</Grid>
           </Border>
</DataTemplate>

I have a button in the application bar on click on that button i am programatically setting the NewDataTemplate which will change 2 item colors to green in the list box .

List box item selector style:

<Style x:Key="ListItemSelectorStyle" TargetType="ListBoxItem">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="Padding" Value="0" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property ="Foreground" Value="Black" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border x:Name="ListBoxItem" Background="{TemplateBinding Background}" 
                                    HorizontalAlignment="{TemplateBinding HorizontalAlignment}" 
                                    VerticalAlignment="{TemplateBinding VerticalAlignment}" 
                                    BorderBrush="{TemplateBinding BorderBrush}" 
                                    BorderThickness="{TemplateBinding BorderThickness}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ListItemBorder" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="#c9ebf2" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled"/>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected"/>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ListItemBorder" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="#c9ebf2" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="ListItemBorder" 
                                    BorderBrush="Transparent" Background="#e3e8f0">
                                <ContentControl x:Name="ContentContainer" 
                                                ContentTemplate="{TemplateBinding ContentTemplate}" 
                                                Content="{TemplateBinding Content}" 
                                                HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                                Margin="{TemplateBinding Padding}" 
                                                VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

This will apply the style when we select the item.

Now this style works good on my DefaultDataTemplate when i click on the item in the list box that means the item gets highlighted, but when the NewDataTemplate is set the style is not showing at all.

How can i fix this ?

Note : I am working on Windows Phone 8 application.

EDIT 1

public class BackgroundConvertor: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            SolidColorBrush solidColorBrush = null;

            if (value != null)
            {
                MyObject obj = value as MyObject ;
                if (parameter != null)
                {
                    if (obj.IsCorrect == 1 && parameter.ToString() == "0")
                    {
                        solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)201, (byte)235, (byte)242)); //blue color                                                       
                    }
                    else if (obj.IsCorrect == 1 && parameter.ToString() == "1")  
                    {
                        solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)201, (byte)242, (byte)169));//green color                                                        
                    }
                    else
                    {
                        solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)227, (byte)232, (byte)240));//Grey color.
                    }
                }
                else if (obj.IsCorrect == 1)
                {
                    solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)201, (byte)242, (byte)169));//green color  
                }

                else
                {
                    solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)227, (byte)232, (byte)240));//Grey color.
                }
            }
            return solidColorBrush;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

EDIT 2

This is my MyObject class:

public class MyObject 
    {
private byte isCorrect;
        public byte IsCorrect
        {
            get { return isCorrect; }
            set
            {
                if (value != this.isCorrect)
                {
                    isCorrect = value;
                }
            }
        }

    }

There are couple of issue with your 2nd DataTemplate .

In Below Code:

<DataTemplate x:Key="NewDataTemplate">
    <Border  
            Background="{Binding Converter={StaticResource BackgroundConvertor}}"
            Margin="0,2,0,0" 
            VerticalAlignment="Stretch"
            HorizontalAlignment="Stretch">
        <Grid> items ...</Grid>
   </Border>
</DataTemplate>

In above code look at :

Background="{Binding Converter={StaticResource BackgroundConvertor}}"

  1. You are not providing any path. Thus your converter will not get any input value.
  2. Also, you should specify the parameters in above binding.

Take a look at below example:

First in your ViewModel declare a property like below :

private MyObject myBackground;
public MyObject MyBackground
{
    get
    {
        return myBackground;
    }
    set
    {
        myBackground = value;
        NotifyPropertyChanged("MyBackground");
    }
}

Fill the values in MyBackground before changing the DataTemplate or in the Constructor of your ViewModel.

In your DataTemplate :

<DataTemplate x:Key="NewDataTemplate">
    <Border  
            Background="{Binding Path=MyBackground, Converter={StaticResource BackgroundConvertor} 
                                 ConverterParameter='1'}" />
            Margin="0,2,0,0" 
            VerticalAlignment="Stretch"
            HorizontalAlignment="Stretch">
        <Grid> items ...</Grid>
   </Border>
</DataTemplate>

The converter you specified in above code should be used here as well.

Note: The above example code is not tested. If there are any errors, then please try to solve it. And if you have any problems please feel free to ask.

Update:

You don't need to make any changes to your Answer Class.

In your ViewModel just declare a property like below:

private Answer myBackground;
public Answer MyBackground
{
    get
    {
        return myBackground;
    }
    set
    {
        myBackground = value;
        OnPropertyChanged("MyBackground");
    }
}

Use the XAML that I mentioned previously in my Answer.

Make changes to your converter like below code:

public class BackgroundConvertor: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush solidColorBrush = null;

        if (value != null)
        {
            Answer answer = (Answer)value ;
            if (parameter != null)
            {
                if (answer.IsCorrect == 1 && parameter.ToString() == "0")
                {
                    solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)201, (byte)235, (byte)242)); //blue color                                                       
                }
                else if (answer.IsCorrect == 1 && parameter.ToString() == "1")  
                {
                    solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)201, (byte)242, (byte)169));//green color                                                        
                }
                else
                {
                    solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)227, (byte)232, (byte)240));//Grey color.
                }
            }
            else if (answer.IsCorrect == 1)
            {
                solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)201, (byte)242, (byte)169));//green color  
            }

            else
            {
                solidColorBrush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)227, (byte)232, (byte)240));//Grey color.
            }
        }
        return solidColorBrush;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM