I have a Border, and i'm trying to to make it's BorderBrush Flashes "Fade in and out". But my problem, is that the Flasing color depends on the code behind. so the color will change, but i have to keep the fade in/out forever, with changing the "From" color of this Border.
I tried in two ways:
1: binding the color directly, but then i know that there's a freezing thing the is needed to be applied on the color:
<Border Grid.Column="1" Grid.Row="2" Name="ActiveBorder" VerticalAlignment="Stretch" Height="auto" BorderBrush="SteelBlue" BorderThickness="2">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetProperty="BorderBrush.Color" Duration="00:00:01" From="{Binding RelativeSource={RelativeSource Self}, Path=FlashBrush}" To="SteelBlue" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
2:starting and stopping the animation from code while changing the color:
<Border Grid.Column="1" Grid.Row="2" Name="ActiveBorder" VerticalAlignment="Stretch" Height="auto" BorderBrush="SteelBlue" BorderThickness="2" >
<Border.Resources>
<Storyboard x:Key="tt" x:Name="tt">
<ColorAnimation AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetProperty="BorderBrush.Color" Duration="00:00:01"
From="{Binding RelativeSource={RelativeSource Self}, Path=FlashBrush}" To="SteelBlue" />
</Storyboard>
</Border.Resources>
</Border>
the code:
Storyboard storyBoard = ActiveBorder.Resources["tt"] as Storyboard;
storyBoard.Stop();
switch (value)
{
case ElementStatus.Active:
FlashBrush = Brushes.LawnGreen;
break;
case ElementStatus.Hold:
FlashBrush = Brushes.Blue;
break;
default:
FlashBrush = Brushes.SteelBlue;
break;
}
storyBoard.Begin(ActiveBorder);
Any ideas? Thanks.
i found the solution: we have to do it in code. without binding.
ColorAnimation myColorAnimation;
public void ChangeAnimationColor(SolidColorBrushFlashBrush)
{
myColorAnimation = new ColorAnimation();
myColorAnimation.From = FlashBrush.Color; // the wanted new color
myColorAnimation.To = Colors.Transparent;
myColorAnimation.AutoReverse = true;
myColorAnimation.RepeatBehavior = RepeatBehavior.Forever;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myColorAnimation);
myStoryboard.Begin(this);
}
and the xml:
<Border Name="ActiveBorder" BorderThickness="2" >
<Border.BorderBrush>
<SolidColorBrush x:Name="MySolidColorBrush" Color="Transparent" />
</Border.BorderBrush>
... Add what ever you want to the Border.
</Border>
Related
I am currently working with a UWP project in Xamarin Forms.
When i use the default SearchBar, it comes with a border that i wish to remove as well as add a rounded background.
I have setup the renderer and some code, but the border is still intact.
public class SearchBar_UWP : SearchBarRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
Control.Background = null;
Control.BorderBrush = null;
}
}
What am I missing in my UWP custom renderer code in order to remove the border and add a rounded background?
Remove border
You could copy the default style and modify BorderThickness property (in test i found we need to change the property on TextBox inside AutoSuggestBox ), then place the new style into Application.Resources , at last apply the style in custom renderer .
custom style in App
<Application.Resources>
<Style TargetType="AutoSuggestBox" x:Key="myStyle">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="TextBoxStyle" Value="{StaticResource AutoSuggestBoxTextBoxStyle}" />
<Setter Property="UseSystemFocusVisuals" Value="{ThemeResource IsApplicationFocusVisualKindReveal}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="AutoSuggestBox">
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Orientation">
<VisualState x:Name="Landscape" />
<VisualState x:Name="Portrait" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox x:Name="TextBox"
Style="{TemplateBinding TextBoxStyle}"
PlaceholderText="{TemplateBinding PlaceholderText}"
Header="{TemplateBinding Header}"
Width="{TemplateBinding Width}"
BorderThickness="0"
ScrollViewer.BringIntoViewOnFocusChange="False"
Canvas.ZIndex="0"
Margin="0"
DesiredCandidateWindowAlignment="BottomEdge"
UseSystemFocusVisuals="{TemplateBinding UseSystemFocusVisuals}" />
<Popup x:Name="SuggestionsPopup">
<Border x:Name="SuggestionsContainer">
<ListView x:Name="SuggestionsList"
Background="{ThemeResource AutoSuggestBoxSuggestionsListBackground}"
BorderThickness="{ThemeResource AutoSuggestListBorderThemeThickness}"
BorderBrush="{ThemeResource AutoSuggestBoxSuggestionsListBorderBrush}"
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
IsItemClickEnabled="True"
ItemTemplate="{TemplateBinding ItemTemplate}"
ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
MaxHeight="{ThemeResource AutoSuggestListMaxHeight}"
Margin="{ThemeResource AutoSuggestListMargin}"
Padding="{ThemeResource AutoSuggestListPadding}" />
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
custom renderer
[assembly: ExportRenderer(typeof(Xamarin.Forms.SearchBar), typeof(MyRenderer))]
namespace App1.UWP
{
class MyRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if(Control != null)
{
Control.Style = App.Current.Resources["myStyle"] as Windows.UI.Xaml.Style;
}
}
}
}
Add Rounded background
Warp SearchBar into Frame , and set CornerRadius on Frame .
<Frame HeightRequest="100" WidthRequest="100" VerticalOptions="Center" HorizontalOptions="Center" BorderColor="Red" CornerRadius="50">
<SearchBar />
</Frame>
I have an UserControl which has listbox. I put this UserControl on the Mainpage.xaml. I would like to handl the selected and button click event on Mainpage.xaml.cs rather than on usercontrol.xaml.cs because I will use this UserControl to another page and the respond will be different. How can I do it? Would you provide example or link to me? Thanks in advance.
There is my UserControl:
<UserControl x:Class="CMSPhoneApp.QueueListControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480"
xmlns:local="clr-namespace:CMSPhoneApp" >
<UserControl.Resources>
<Style x:Key="ScrollViewerStyle1" TargetType="ScrollViewer">
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ScrollStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Scrolling">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalScrollBar"/>
</Storyboard>
</VisualState>
<VisualState x:Name="NotScrolling"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Margin="{TemplateBinding Padding}">
<ScrollContentPresenter x:Name="ScrollContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}"/>
<ScrollBar x:Name="VerticalScrollBar" HorizontalAlignment="Right" Height="Auto" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Opacity="0" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" VerticalAlignment="Stretch" Width="5" BorderBrush="#FF2022BC"/>
<ScrollBar x:Name="HorizontalScrollBar" HorizontalAlignment="Stretch" Height="5" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Opacity="0" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}" VerticalAlignment="Bottom" Width="Auto"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<local:VisibilityConverter x:Key="VisibilityConverter"/>
<local:ColumSpanConverter x:Key="ColumSpanConverter"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer Style="{StaticResource ScrollViewerStyle1}" Background="#00E23162">
<ListBox x:Name="lstCall" HorizontalAlignment="Left" Margin="6,6,0,0" VerticalAlignment="Top" Width="400" SelectionChanged="lstCall_SelectionChanged" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="grdQueue" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35" />
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="125" />
</Grid.ColumnDefinitions>
<Image Source="{Binding Type}" Grid.Row="0" Grid.Column="0"/>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan= "{Binding isSpan, Converter={StaticResource ColumSpanConverter}}" Text="{Binding summary}" TextWrapping="Wrap"
Style="{StaticResource PhoneTextAccentStyle}" />
<Button Grid.Row="0" Grid.Column="3" ClickMode="Press" Click="Action_Click" Style="{StaticResource ButtonStyle1}"
Visibility="{Binding isVisibility, Converter={StaticResource VisibilityConverter}}">
<Button.Content>
<TextBlock Width="85" Height="70" Text="{Binding ActionCaption}"
Style="{StaticResource LabelStyle_20}" />
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
</Grid>
</UserControl>
There is the code to add the UserControl on Mainpage.xaml:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<my:QueueListControl />
</StackPanel>
</Grid>
</Grid>
I am able to bind the data on the lst on MainPage.xaml.cs by the following code:
MyQueue = new List<QueueItem>();
MyQueue.Add(new QueueItem { summary = "Test1tqeewwewew332233 3233322323 wdqwqwqwqwq", status = "Open", callNumber = "1" });
MyQueue.Add(new QueueItem { summary = "Test1tqeewwewew332233 3233322323 wdqwqwqwqwq", status = "Responded", callNumber = "2" });
MyQueue.Add(new QueueItem { summary = "Test1tqeewwewew332233 3233322323 wdqwqwqwqwq", status = "Resolved", callNumber = "3" });
MyQueue.Add(new QueueItem { summary = "Test1tqeewwewew332233 3233322323 wdqwqwqwqwq", status = "transfer", callNumber = "4" });
MyQueue.Add(new QueueItem { summary = "Test1tqeewwewew332233 3233322323 wdqwqwqwqwq", status = "Complete", callNumber = "5" });
test.lst.ItemsSource = MyQueue;
One solution is to use a library such as MVVM Light; it has a Messenger class (tutorial) that you can use to send messages from the UserControl's code behind.
In the MainPage's OnNavigatedTo method register for the UserControl's message and in the 'OnNavigatedFrom` method un-register from listening to the message. You can do the same in the other page where you want to use this UserControl.
The message fired by the UserControl must contain all the relevant information needed for either class to react to it appropriately. Thus, you can keep the control's code-behind decoupled from user interaction logic.
You need to make your UserControl more re-useable by exposing its state and events so that these can be updated / handled by controls that host an instance of your control. See this tutorial for details:
A Simple Pattern for Creating Re-useable UserControls in WPF / Silverlight
I show some items from the database in the list and I want the user to be able to mark some of them as favorites. The best way would be to show some star icon for user to click on which then would turn into slightly different star to indicate that the item is now favorite. What controls should I use for those stars? Could I bind them to some boolean property of the item?
You can also use vector graphics to achieve this without using png icons.
I created this style a while a go, basically it is for CheckBox but I think it also works for ToggleButton by simply changing the TargetType from CheckBox to ToggleButton.
By setting the IsChecked of either CheckBox or ToggleButton to True, the star will be filled with the accent color of the phone.
The Style
<Style x:Key="StarCheckBoxStyle" TargetType="CheckBox">
<Setter Property="Background" Value="{StaticResource PhoneAccentBrush}" />
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused" />
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.2000000" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="check" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate" />
<VisualState x:Name="Unchecked" />
</VisualStateGroup>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid" />
<VisualState x:Name="InvalidUnfocused" />
<VisualState x:Name="InvalidFocused" />
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.2000000" />
</VisualStateGroup.Transitions>
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled" />
<VisualState x:Name="Normal" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="check" Stretch="Fill" Height="48" Width="48" UseLayoutRounding="False" Data="M16.000002,0 L19.77688,12.223213 L32,12.222913 L22.111122,19.776972 L25.888546,32 L16.000002,24.445454 L6.1114569,32 L9.8888807,19.776972 L8.574415E-09,12.222913 L12.223121,12.223213 z" Opacity="0" Fill="{TemplateBinding Background}" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Path x:Name="stroke" Stretch="Fill" Stroke="{TemplateBinding Background}" Height="48" Width="48" UseLayoutRounding="False" Data="M16.000002,0 L19.77688,12.223213 L32,12.222913 L22.111122,19.776972 L25.888546,32 L16.000002,24.445454 L6.1114569,32 L9.8888807,19.776972 L8.574415E-09,12.222913 L12.223121,12.223213 z" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,0,8,0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Apply the style
<CheckBox Content="unchecked state" Style="{StaticResource StarCheckBoxStyle}" />
<CheckBox IsChecked="True" Content="checked state" Style="{StaticResource StarCheckBoxStyle}" />
How they look
You can use a ToggleButton to do this. Keep 2 star images in your project, one for clicked and the other for not clicked. You can use data binding along with the IsChecked property to switch between the 2 images.
XAML:
<ToggleButton IsChecked="{Binding IsFavorited, Mode=TwoWay}">
<ToggleButton.Content>
<Image Source="{Binding FavoriteImage}" />
</ToggleButton.Content>
</ToggleButton>
C#:
Image ClickedImage = new Image() {
Source = new BitmapImage(new Uri("/clicked.png", UriKind.Relative));
};
Image NotClickedImage = new Image() {
Source = new BitmapImage(new Uri("/not_clicked.png", UriKind.Relative));
};
bool _isFavorited = false;
Image _favoriteImage = NotClickedImage;
public bool IsFavorited
{
get { return _isFavorited; }
set
{
if( _isFavorited != value ) {
_isFavorited = value;
NotifyPropertyChanged( "IsFavorite" );
FavoriteImage = _isFavorited ? ClickedImage : NotClickedImage;
}
}
}
public Image FavoriteImage
{
get { return _favoriteImage; }
private set
{
if( _favoriteImage != value ) {
_favoriteImage = value;
NotifyPropertyChanged( "FavoriteImage" );
}
}
}
The class containing the code behind needs to implement the INotifyPropertyChanged interface.
Refer here for a list of star controls available for the silverlight toolkit for the windows phone.
I have the following situation:
public class EbookPhotoSummary : ContentControl
{
...
#region Construtores
public EbookPhotoSummary()
{
DefaultStyleKey = typeof(EbookPhotoSummary);
this.Loaded += new RoutedEventHandler(EbookPhotoSummary_Loaded);
}
...
}
This ContentControl has a Style definition (I'm only displaying the important part):
<Style TargetType="local:EbookPhotoSummary">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:EbookPhotoSummary">
<Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="EbookListingStates">
<VisualState x:Name="EbooksThumbnail"/>
<VisualState x:Name="EbooksList">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="hplMore">
<DiscreteObjectKeyFrame KeyTime="0" Value="[link]"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="LayoutRoot" Height="235">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ContentControl Content="{Binding CoverImage}" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0"/>
<Grid Margin="10,0,0,0" Grid.Column="1">
...
<HyperlinkButton Name="hplMore" Content="{Binding Path=LocalizedResources.Button_Text_More_Library, Source={StaticResource LocalizedStrings}}" Foreground="{StaticResource PhoneAccentBrush}" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="3"/>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then, I put this ContentControl as DataTemplate of a ListBox:
<ListBox x:Name="lsbEbooksInLibrary" ItemsSource="{Binding}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="Transparent">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Add Color" Click="ContextMenuItem_Click"/>
<toolkit:MenuItem Header="Remove Color" Click="ContextMenuItem_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<local:EbookPhotoSummary x:Name="ebookTeste" Margin="0,0,0,10">
...
</local:EbookPhotoSummary>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What I want is when I click an ApplicationBar's button, the "EbooksList" VisualState be applied, which I'm trying to do this way:
private void mniVisualizationMode_Click(object sender, EventArgs e)
{
this.GetItemsRecursive(lsbEbooksInLibrary);
lsbEbooksInLibrary.UpdateLayout();
}
and
private void GetItemsRecursive(DependencyObject lb)
{
var childrenCount = VisualTreeHelper.GetChildrenCount(lb);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(lb, i);
if (child is ListBoxItem)
{
VisualStateManager.GoToState(child as Control, "EbooksList", false);
}
GetItemsRecursive(child);
}
}
but nothing happens. I already know that GoToState is returning false, but I don't know why. Any ideas?
Thanks in advance.
I have a ListBox in a WP7 app page which I bind to a collection (List) of a custom object called Location. In that object is a field called WMO and what I want to do when the ListBox loads is set the foregound color of whatever bound listbox item has that same value as my default value... but I just can't seem to get this working and nothing I've read or googled has helped.
I know the items in the list are bound to the datasource but I want to get to the physical representation of that item and change the foreground colour.... just can't work out how I do that so if anyone can help I'd appreciate it.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0" >
<ScrollViewer Height="615" HorizontalAlignment="Left" Margin="5,5,5,5" Name="scrollViewer1" VerticalAlignment="Top">
<ListBox Name="lbxSavedLocs" Height="615" FontSize="22" HorizontalAlignment="Left" VerticalAlignment="Top" Width="470" SelectionChanged="lbxSavedLocs_SelectionChanged" Loaded="lbxSavedLocs_Loaded">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="380" Text="{Binding SiteName}" HorizontalAlignment="Left" />
<TextBlock Width="90" Text="{Binding WMO}" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
private void lbxSavedLocs_Loaded(object sender, RoutedEventArgs e)
{
//Populate the listbox from our saved locations.
lbxSavedLocs.ItemsSource = gl.savedLocs.OrderBy(x => x.SiteName);
foreach (Location itm in lbxSavedLocs.Items)
{
if (loc.WMO == gl.defaultWMO)
{
//GET AN "INVALID CAST" EXCEPTION HERE:
((ListBoxItem)itm).Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
}
}
//Hopefully this produces a redraw of the ListBox.
lbxSavedLocs.InvalidateArrange();
}
Try this:
Option1:
ListBoxItem lbi1 = (ListBoxItem)(listBox.ItemContainerGenerator.ContainerFromIndex(0));
lbi1.Foreground= new SolidColorBrush(Color.FromArgb(100, 45, 23, 45));
Option2:
ListBoxItem lbi2 = (ListBoxItem)(listBox.ItemContainerGenerator.ContainerFromItem(listBox.Items.SelectedItem));
lbi2.Foreground= new SolidColorBrush(Colors.Red);
If you need to apply the same foreground colour to all items in the ListBox or to bind the foreground colour to a value in the data item, then the best approach is to modify the ItemContainerStyle. The ItemContainerStyle defines the visual wrapper around the contents of the ItemTemplate and by default uses a ContentControl that you can set or bind the Foreground property:
<Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"
Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0"
To=".5"
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="ContentContainer"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Foreground="#FFFF0000"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Background="Black"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here is a way....i think it works
The property you want to bind is Foreground, so
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0" >
<ScrollViewer Height="615" HorizontalAlignment="Left" Margin="5,5,5,5" Name="scrollViewer1" VerticalAlignment="Top">
<ListBox Name="lbxSavedLocs" Height="615" FontSize="22" HorizontalAlignment="Left" VerticalAlignment="Top" Width="470" SelectionChanged="lbxSavedLocs_SelectionChanged" Loaded="lbxSavedLocs_Loaded">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="380" Text="{Binding SiteName}" Foreground="{binding forgroundColor}" HorizontalAlignment="Left" />
<TextBlock Width="90" Text="{Binding WMO}" Foreground="{binding forgroundColor}" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
In the program put up the apt condition where you populate your listbox to choose the right Forground using foregroundColor
Populate the list box using a class containin
class lisboxItem
{
public string SiteName{get;set;}
public string forgroundColor{get;set;}
public string WMO{get;set;}
}
create a List<listboxItem> items=new List<listboxItem>();
and fill the list items in a loop where u give the condition you want.
after that
call
lbxSavedLocs.ItemSource=items