Customized MultiSelectList in windows phone 8 app - wpf

In my app, when i am clicking on a button btn_setting this convas visibility is visible so it is showing like a popup having multiselect list with OK and Cancel buttons but the problem i am facing is that i want to add items in multiselectlist dynamically with checkbox border colour blue and foreground color to be black and the most important after every item i want a horizontal blue-line as a separator between two items.
I put foreground ="Black" for MultiSelectList but itis showing the white colour for the items.
<Canvas x:Name="Setting_popup" Width="485" Height="770" Visibility="Collapsed">
<Border Margin="10" >
<StackPanel Background="White">
<toolkit:MultiselectList x:Name="Setting_list" Background="Blue" Width="456" Height="700" FontWeight="Bold" Foreground="Black">
<CheckBox Content="Celsius" />
<CheckBox Content="Fahrenheit"/>
<CheckBox Content="Kelvin"/>
<CheckBox Content="Rankine"/>
</toolkit:MultiselectList>
<StackPanel Orientation="Horizontal">
<Button x:Name="btn_OK" Content="Ok" Width="223" HorizontalAlignment="Left" Foreground="White" Background="#FF3498DB" />
<Button x:Name="btn_Cancel" Content="Cancel" Width="223" HorizontalAlignment="Right" Foreground="White" Background="#FF3498DB" Click="Button_Click_1" />
</StackPanel>
</StackPanel>
</Border>
</Canvas>

You can change the check boxes style, for example:
<phone:PhoneApplicationPage.Resources>
<Style x:Key="CheckBoxStyle1" TargetType="CheckBox">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="Foreground" Value="Black"/>
</Style>
</phone:PhoneApplicationPage.Resources>
And then set the style to each check box:
<toolkit:MultiselectList x:Name="Setting_list" Width="456" Height="400" >
<CheckBox Content="Celsius" Style="{StaticResource CheckBoxStyle1}" />
<CheckBox Content="Fahrenheit" Style="{StaticResource CheckBoxStyle1}"/>
<CheckBox Content="Kelvin" Style="{StaticResource CheckBoxStyle1}"/>
<CheckBox Content="Rankine" Style="{StaticResource CheckBoxStyle1}"/>
</toolkit:MultiselectList>

Related

Vertical alignment of ContentControl in styled ListBox

I am using this answer to style a ListBox as RadioButton in order to simplify my MVVM code by driving the selection of the checked radio button via an enum - rather than having a bunch of bools that I have to manually map back and forth to the enum.
This works really well when the ListBoxItem content is a simple line of text. The radio button aligns with the text and all is happy. But when I change the content to be a UserControl, the radio button for that choice gets rendered at the vertical mid-point of the UserControl rather than at the top (where I want it).
Here is some code and an image that better explains what I am trying to do (Note that a bunch of stuff has been left out for clarity):
The UserControl that I am inserting as content into one of the choices
<UserControl x:Class="TestCtl">
<StackPanel Orientation="Vertical" >
<Label Margin="-5,0,0,0" Content="Choice #2"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
</UserControl>
The ListBox (with the aforementioned style defined elsewhere)
<StackPanel Orientation="Vertical">
<ListBox SelectedValuePath="Tag"
Style="{StaticResource RadioButtonList}"
SelectedValue="{Binding Blah Blah"}>
<ListBoxItem Tag="Choice1" Content="Choice #1" />
<ListBoxItem Tag="Choice2">
<ContentControl>
<subf:TestCtl />
</ContentControl>
</ListBoxItem>
<ListBoxItem Tag="Choice3" Content="Choice #3"/>
<ListBoxItem Tag="Choice4" Content="Choice #4" />
</ListBox>
<ComboBox blah blah/>
</StackPanel>
What it looks like when rendered:
I have tried setting both the VerticalAlignment and VerticalContentAlignment as well as playing with Margin and Padding in every location I can think of in both my xaml code and the style that I linked to, but no matter what I set I can't get the radio button and user control to align at their tops.
Is there anyway to achieve what I want by modifying either the style I am using or my code? Or am I just flat out doing this wrong?
In the RabioButtonList style change this:
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderThickness="0" Background="Transparent">
<!-- CHANGE THIS -->
<StackPanel Orientation="Horizontal">
<RadioButton
Focusable="False"
IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}"/>
<ContentPresenter />
</StackPanel>
<!------------------>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
In the user control set the label Padding to 5,0,0,0 (Thanks to mm8)
<StackPanel Orientation="Vertical" >
<Label Margin="-5,0,0,0" Content="Choice #2" Padding="5,0,0,0"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
Set the Padding of the Label to 0:
<ListBoxItem Tag="Choice1" Content="Choice #1" />
<ListBoxItem Tag="Choice2">
<UserControl>
<StackPanel Orientation="Vertical" >
<Label Content="Choice #2" Padding="0"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
</UserControl>
</ListBoxItem>
<ListBoxItem Tag="Choice3" Content="Choice #3"/>
<ListBoxItem Tag="Choice4" Content="Choice #4" />
This should fix the vertical alignment issue. But you shouldn't have to use a ListBox in the first place to be able to bind a RadioButton to a single source property:
WPF + MVVM + RadioButton : Handle binding with single property

WPF buttons with both image and text

Here is my control template for the button style.
<StackPanel Orientation="Horizontal">
<Image x:Name="EmailImage" Source="../Images/btn__icon_savedisk.png" Height="17" Width="17" Stretch="None" RenderOptions.BitmapScalingMode="NearestNeighbor" />
<TextBlock x:Name="EmailImageTxt" Margin="20,0,20,0" Foreground="White" Text="{x:Static res:Localize.SAVE}" Background="{x:Null}" />
</StackPanel>
My problem is when I get mouse pointer over the area with the space between image and text button(image and text) is not selecting. I need to have mouse focus on all over the buttons.
Thank you for your help.
Set Background="Transparent" to stackpanel and it works as expected.
An control with no background is usually called as non-hittable in XAML terms. So it is must to set a background to make the object respond to hits.
<Button VerticalAlignment="Center" HorizontalAlignment="Center">
<Button.Template>
<ControlTemplate>
<StackPanel x:Name="stackpanel" Orientation="Horizontal">
<Image x:Name="EmailImage" Source="Black.jpg" Height="17" Width="17" Stretch="None" RenderOptions.BitmapScalingMode="NearestNeighbor" />
<TextBlock x:Name="EmailImageTxt" Margin="20,0,20,0" Foreground="Black" Text="gdfgdg}" Background="{x:Null}" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" TargetName="stackpanel"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>

WPF Metro Styling ListBox

I'm having a problem styling my ListBox selection background.
I used ListView originally, it was less problematic with styling but moving this to Silverlight app, I found out that it doesn't have ListView so I just used ListBox.
I want my app to be easily ported in Silverlight and also in Windows Phone so I used ListBox and now am having a trouble with the style.
My Metro app has Dark theme and I have custom ListBoxItem but am not sure why when I clicked on it, it looks like this
originally when using ListView, it looks like this
adding background color in my custom ItemsTemplate make it look this
How do I get rid of that White background and also restyle the item when hovered because it looks like this
this my XAML for listbox so far
<ListBox Grid.Row="3" Name="lvSubmeters" VerticalAlignment="Top" HorizontalAlignment="Stretch" SelectedItem="{Binding Path=SelectedListViewItem, Mode=TwoWay}" SelectedIndex="{Binding Path=SelectedListViewIndex, Mode=TwoWay}" ItemTemplate="{StaticResource SubmeterItems}" ItemsSource="{Binding Path=Store.AllItems}" Background="{x:Null}" Foreground="White">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Margin" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
and also if you want my custom ItemsTemplate
<DataTemplate x:Name="SubmeterItems">
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch" Margin="5,5,5,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="166"/>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Top">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="{Binding MeterID}" FontSize="24" FontWeight="Bold" Foreground="#FF429AA3" />
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="{Binding Fullname}" FontSize="16" />
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Height="95">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=" " FontSize="24" FontWeight="Bold" Foreground="#FF429AA3" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="29*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Grid.Column="0" VerticalAlignment="Top" Text="Last Reading:" FontSize="14" Margin="0,0,5,5" />
<TextBlock Grid.Column="0" VerticalAlignment="Top" Text="New Reading:" FontSize="14" Margin="0,0,5,5" />
<TextBlock Grid.Column="0" VerticalAlignment="Top" Text="KW/H Used:" FontSize="14" Margin="0,0,5,5" />
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Grid.Column="1" VerticalAlignment="Top" Text="{Binding LastReading}" FontSize="14" Margin="0,0,5,5" FontWeight="Bold" />
<TextBlock Grid.Column="1" VerticalAlignment="Top" Text="{Binding NewReading}" FontSize="14" Margin="0,0,5,5" FontWeight="Bold" />
<TextBlock Grid.Column="1" VerticalAlignment="Top" Text="{Binding KwHUsed}" FontSize="14" Margin="0,0,5,5" FontWeight="Bold" />
</StackPanel>
</Grid>
</StackPanel>
<StackPanel Grid.Column="2" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Background="Black">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="{Binding KwhUsedAmount}" FontSize="20" FontWeight="Bold" Foreground="Red" TextAlignment="Right" Margin="0,0,5,0" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="+" FontSize="20" Foreground="#99FF0000" TextAlignment="Right" Margin="0,0,5,0"/>
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="{Binding AdditionalCharges}" FontSize="20" Foreground="#99FF0000" TextAlignment="Right" Margin="0,0,5,0"/>
</StackPanel>
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="{Binding TotalAmount}" FontSize="34" FontWeight="Bold" Foreground="Green" TextAlignment="Right" Margin="0,0,5,0" />
</StackPanel>
</Grid>
</DataTemplate>
I tried taking this to Blend 4 but I can't find the way to do it.
It looks to me like your screenshots from above don't quite match the XAML that you've provided, however I think I can answer your questions.
For the white border around each item - From the way that the border changes to Purple when the item is selected, you can tell that it is part of the ItemContainer (because that is what gets selected). The ItemContainer will contain the Content of each ListBoxItem. The Content is rendered using the DataTemple (or ItemTemplate property). In your DataTemplate, you have a margin of 5 around the topmost grid, meaning that when the Content is rendered using that DataTemplate, there will be a margin around the outside of the content. That seems to be what you're getting with your white border around each item, so I'm pretty sure that's what is going on. Get rid of the margin in the top most grid of the DataTemplate, and the white border will be gone. If this isn't correct, please provide more complete XAML example (including the parent XAML element of the Listbox) because the xaml above, on its own, does not yield a white border when the Window background is Black.
Changing the colors/style of the ListBoxItem is pretty easy, and there are several ways to do it. The easiest way (in my opinion) is to add a trigger to the ItemContainerStyle that adjusts the background color on MouseOver. Here is a simple example, extending your existing ItemContainerStyle (triggers can be much more advanced, if you wish):
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Margin" Value="5" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
Hope that helps.

Color a WPF ListBox item based on a property

I have an observable collection of Song objects. These song objects have a property called "Playing" that is a bool (bad naming, I know). The songs display in a ListBox in my application. I want the song that is Playing to be colored red. I have been working with triggers all day trying to make this work. So far, I have gotten to the point where they are colored based on what Playing is set to when the song is added to the list. Is it possible to make it change when the Playing property changes?
Here is my XAML:
<Window x:Class="MusicPlayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MusicPlayer="clr-namespace:MusicPlayer" Title="Music" Height="350" Width="525" Name="Main">
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<Button Content="Play" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayButton_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Center" Margin="0,0,165,20" Name="stopButton" VerticalAlignment="Bottom" Width="75" Click="stopButton_Click" />
<Button Content="Next" Height="23" HorizontalAlignment="Center" Margin="165,0,0,20" Name="nextButton" VerticalAlignment="Bottom" Width="75" Click="nextButton_Click" />
<Button Content="Add Songs..." Height="23" HorizontalAlignment="Center" Margin="330,0,0,20" Name="AddButton" VerticalAlignment="Bottom" Width="75" Click="AddButton_Click" />
<Button Content="Previous" Height="23" HorizontalAlignment="Center" Margin="0,0,0,20" Name="PreviousButton" VerticalAlignment="Bottom" Width="75" Click="PreviousButton_Click" />
<Button Content="Pause" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Visibility="Hidden" Click="PauseButton_Click" />
<Menu Height="23" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Quit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<Slider Height="23" HorizontalAlignment="Stretch" Margin="10,0,10,50" Name="ProgressBar" VerticalAlignment="Bottom" />
</Grid>
</Window>
Edit:
After implementign INotifyPropertyChanged, The color will change to red using either the above or below XAML. Now, it won't change back white using either method. I am also having a problem where my Play method will not change the background color to red, but my next method will. Here is my code: http://pastebin.com/EMTUpTin http://pastebin.com/LuK78zGp
Here is my new XAML:
<Window x:Class="MusicPlayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MusicPlayer="clr-namespace:MusicPlayer" Title="Music" Height="350" Width="525" Name="Main">
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}">
<TextBlock.Background>
<SolidColorBrush Color="{Binding BackgroundColor}"/>
</TextBlock.Background>
</TextBlock>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<Button Content="Play" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayButton_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Center" Margin="0,0,165,20" Name="stopButton" VerticalAlignment="Bottom" Width="75" Click="stopButton_Click" />
<Button Content="Next" Height="23" HorizontalAlignment="Center" Margin="165,0,0,20" Name="nextButton" VerticalAlignment="Bottom" Width="75" Click="nextButton_Click" />
<Button Content="Add Songs..." Height="23" HorizontalAlignment="Center" Margin="330,0,0,20" Name="AddButton" VerticalAlignment="Bottom" Width="75" Click="AddButton_Click" />
<Button Content="Previous" Height="23" HorizontalAlignment="Center" Margin="0,0,0,20" Name="PreviousButton" VerticalAlignment="Bottom" Width="75" Click="PreviousButton_Click" />
<Button Content="Pause" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Visibility="Hidden" Click="PauseButton_Click" />
<Menu Height="23" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Quit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<Slider Height="23" HorizontalAlignment="Stretch" Margin="10,0,10,50" Name="ProgressBar" VerticalAlignment="Bottom" />
</Grid>
</Window>
Edit 2:
I just noticed I am having another problem. If I highlight one of the items with a white background, the text is invisible. How do I fix this?
Edit 3:
Fixed this problem by setting the background to Colors.Transparent instead of Colors.White.
In order to have it change back, wouldn't you also have to implement a trigger for when Playing is False? Like so:
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Playing}" Value="False">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>
This seems like the simplest solution to me. Of course you can change Value="White" to whatever color you need.
Does your object with the Playing property implement INotifyPropertyChanged ? If it does, then your UI should auto-update based on the DataTrigger approach you are using.
Another approach is to use ViewModels instead of Triggers (easier to understand and work with - when things don't go as expected) An example
Update:
Just looked at your code snippets. One thing I found - you need to trigger the event after you've applied the new value.
public Color BackgroundColor
{
get { return _backgroundColor; }
set
{
_backgroundColor = value;
NotifyPropertyChanged("BackgroundColor"); // must be after so that new value is readable by the GUI
}
}
Also the dataTemplate must be applied to the ItemTemplate property of the listbox
<ListBox.ItemTemplate> <!-- not Resources property -->
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
I basically changed the snippet from the example that I posted to use your song class and then modified the button click to toggle between 2 colors. (Also turned ListView into ListBox)
private bool _isGreen = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (var item in Items)
item.BackgroundColor = (_isGreen ? Colors.Cyan : Colors.PaleGreen );
_isGreen = !_isGreen;
}
My listboxes change color on every click! :)

Display Tooltip in Center of Screen

Using Grid to display pictures around edge of screen.
<Image Source="...." Grid.Row="0" Grid.Column="0">
<Image.Tooltip>
<TextBlock>Some narrative..</TextBlock>
<TextBox Name="ToolTipText" Grid.Row="1" Grid.Column="1" />
On MouseOver I want the tooltip to appear in TextBox, but it aways appears centered over the image.
<Style TargetType="ToolTip">
<Setter Property="PlacementTarget"
Value="{Binding ElementName=ToolTipText, Path=Text} />
<Setter Property="Placement" Value="Center" />
Try this
<Grid Name="mainGrid">
<Image Source="...." Grid.Row="0" Grid.Column="0" ToolTipService.PlacementTarget="{Binding ElementName=mainGrid}">
<Image.ToolTip>
<ToolTip Placement="Center">
<TextBlock>Some narrative..</TextBlock>
</ToolTip>
</Image.ToolTip>
</Image>
</Grid>
This
ToolTipService.PlacementTarget="{Binding ElementName=mainGrid}"
Can be replaced by
ToolTipService.PlacementTarget="{Binding RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"

Resources