ValueConverter doesn't work in FlipView - c#

I have a ListView in a FlipView
<FlipView
x:Name="flipView"
AutomationProperties.AutomationId="ItemsFlipView"
AutomationProperties.Name="Item Details"
TabIndex="1"
Width="Auto"
Grid.Row="2"
Grid.Column="1"
VerticalAlignment="Top"
HorizontalAlignment="Center"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}" Padding="0" VirtualizingStackPanel.VirtualizationMode="Standard">
<FlipView.ItemTemplate>
<DataTemplate>
<!--
UserControl chosen as the templated item because it supports visual state management
Loaded/unloaded events explicitly subscribe to view state updates from the page
-->
<UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Orientation="Vertical" Margin="0,100,0,0">
<ListView x:Name="ListofOptions" Height="400" Width="280"
ItemsSource="{Binding QuestionOptions}" SelectedValue="{Binding Answer,Mode=TwoWay}"
IsEnabled="{Binding IsEnabled,Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<StackPanel.Resources>
<common:AltBackgroundConverter x:Key="BGConvertor" />
</StackPanel.Resources>
<StackPanel.Background>
<SolidColorBrush Color="{Binding IndexWithinParentCollection, Mode=OneWay, Converter={StaticResource BGConvertor}}"></SolidColorBrush>
</StackPanel.Background>
<TextBlock Text="{Binding OptionValue}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Grid>
</UserControl>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I write a value conventor of ListView for changing background of alternative row. here is Conventor's code
public class AltBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (!(value is int)) return null;
int index = (int)value;
if (index % 2 == 0)
return Colors.White;
else
return Colors.LightGray;
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
when the listbox is out of FlipView everything is Ok but the Conventor doesn't execute when the ListView is in a FlipView. please advice me.

Created a new Split XAML project in VS2012 and added your converter there and used it in ListView and it was still working after moving the ListView inside a FlipView.
I'm now guessing it's a binding issue, happening because root binding object has changed and one of the bindings not resolved as we expect. have you tried moving the Resources tag to upper level which is the FlipeView?
P.S. This is more of a comment, but I don't have reputation for comments!

Related

Fixed Proportional Sizing in WPF

I have a wpf grid with two columns that should be equally spaced. I know about star (*) sizing, but when I set the column width to be equally spaced, the actual column changes at runtime. The overall width of the grid will change based on the window size, but I want to force the two columns to always be of equal width inside that grid.
I've currently got a lot of nested elements assigned to the first column, and the second column only has an ItemsControl panel which only shows items when a button event action is taken... so there are times when it's empty. My assumption is that because the second column is empty, the first column is automatically taking up as much space as it can. Is there a way to force the columns to remain proportionally fixed? Here's my basic setup:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<!-- Lots of nested WPF elements inside this stack panel -->
</StackPanel>
<ItemsControl Grid.Column="1" ItemsSource="{Binding Tasks}">
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}" >
<ItemsPresenter/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="cc:Tasks">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
I've read this thread, but I'm not entirely sure if that answer fits this problem.
Following #Paparazzi advice, I created a converter to bind the width of the scrollviewer. Here's how I did it:
In the C# code behind, I create the converter:
public class PercentageConverter : MarkupExtension, IValueConverter
{
private static PercentageConverter _instance;
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _instance ?? (_instance = new PercentageConverter());
}
}
Then, in my .xaml code, I use it like this:
<UserControl.Resources>
<ResourceDictionary>
<local:PercentageConverter x:Key="PercentageConverter"></local:PercentageConverter>
</ResourceDictionary>
</UserControl.Resources>
<Grid Name="ParentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0"
HorizontalScrollBarVisibility="Auto"
MinWidth="200"
Width="{Binding Path=ActualWidth, ElementName=ParentGrid, Converter={StaticResource PercentageConverter}, ConverterParameter='0.6'}">
<StackPanel Orientation="Vertical" ScrollViewer.CanContentScroll="True">
<!-- Lots of other WPF Framework elements -->
</StackPanel>
</ScrollViewer>
<ItemsControl Grid.Column="1" ItemsSource="{Binding Tasks}">
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}" >
<ItemsPresenter/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="cc:Tasks">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
The key is to define the converter in the ResourceDictionary. Then, I set the width property of the ScrollViewer element to bind to the actual width of the parent grid, using the converter to set it to a certain percentage (in this case 0.6 is the parameter or 60% of the overall width of the parent grid). I hope this helps someone in the future.

UWP App Randomly Crashes When Returning to Previous Page

I have an app where I list some items and then change to another page for editing. In the edit page, I have some fields where i need to choose a value from a list which I load in another page. I call the list page from the edit page, passing a method from the edit page view model to be invoked when a selection is made so that I can update my model and bindings.
The problem is that sometimes, when returning to the edit page, the debugger breaks in the generated file App.g.i.cs with an
"Error HRESULT E_FAIL has been returned from a call to a COM component." exception.
It fully displays the page with the correct bindings and selected values before breaking.
I've excluded possible errors from the async loading of the value list by replacing it with a dummy page and by removing any callbacks set by the edit page. The error still happened.
The edit page has its navigation cache mode set to Required so I don't lose the previous changes. I tried without a required cache mode and still got the error.
The only thing that seemed to resolve the issue was when I removed the bindings that used custom converters from the edit page xaml but I have those in other pages and never had a problem. (See Update)
The debugger break in the generated code:
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
This is the xaml for the edit page:
<Page.Resources>
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibility" />
<converters:StringFormatConverter x:Key="StringFormat" />
<converters:DateTimeToDateTimeOffsetConverter x:Key="DateOffset" />
<converters:DateTimeToTimeSpanConverter x:Key="TimeSpan" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<fieldSelectControl:BackButtonAndTitle Title="Page Title" />
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Name="HomeButton"
Width="70"
Height="50"
Background="Black"
Content=""
FontFamily="Segoe MDL2 Assets"
FontSize="30" />
<TextBlock Name="PageTitle"
FontSize="36"
Text="{Binding OrderTitle}" />
</StackPanel>
<ProgressRing Grid.Row="2" IsActive="{Binding IsLoading}" />
<ScrollViewer Grid.Row="2"
Height="Auto"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
Visibility="{Binding Path=FinishedLoading,
Converter={StaticResource BoolToVisibility}}">
<StackPanel Margin="20,10,20,30">
<TextBlock Margin="0,5,0,5"
Style="{StaticResource DetailLabel}"
Text="Date" />
<DatePicker Date="{Binding Day, Mode=TwoWay, Converter={StaticResource DateOffset}}" />
<TextBlock Margin="0,15,0,5"
Style="{StaticResource DetailLabel}"
Text="Type" />
<ComboBox ItemsSource="{Binding ComboValues}" SelectedItem="{Binding SelectedHourType, Mode=TwoWay}" />
<TextBlock Margin="0,15,0,5"
Style="{StaticResource DetailLabel}"
Text="Start" />
<TimePicker ClockIdentifier="24HourClock" Time="{Binding StartTime, Mode=TwoWay, Converter={StaticResource TimeSpan}}" />
<TextBlock Margin="0,5,0,5"
Style="{StaticResource DetailLabel}"
Text="End" />
<TimePicker ClockIdentifier="24HourClock" Time="{Binding EndTime, Mode=TwoWay, Converter={StaticResource TimeSpan}}" />
<TextBlock Margin="0,15,0,5"
Style="{StaticResource DetailLabel}"
Text="Amount" />
<TextBox InputScope="Number" Text="{Binding HValue, Mode=TwoWay}" />
<fieldSelectControl:FieldWithIconSelector x:Name="fsSelect"
IconClickedEvent="btnClose_Click"
IconField=""
TitleField="Add..."
TitleIconField=""
ValueField="" />
<ScrollViewer Height="Auto"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<ListView x:Name="lstOrders"
Height="auto"
MaxHeight="600"
HorizontalAlignment="Stretch"
IsItemClickEnabled="True"
ItemClick="lstOrders_ItemClick"
ItemsSource="{Binding SelectedEmployees,
Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:Responsible">
<fieldSelectControl:FieldWithIconSelector x:Name="fsEmployees"
IconClickedEvent="fsEmployees_IconClickedEvent"
IconField=""
TitleField=""
TitleIconField=""
ValueField="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</ScrollViewer>
<Button Name="btnSave"
Margin="0,20,0,15"
HorizontalAlignment="Stretch"
Click="btnSave_Click"
Visibility="{Binding Path=FinishedSaving,
Converter={StaticResource BoolToVisibility}}">
<Button.Template>
<ControlTemplate>
<StackPanel HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="#0099cc"
Orientation="Vertical"
Padding="5">
<TextBlock HorizontalAlignment="Center"
FontFamily="Segoe MDL2 Assets"
FontSize="25"
Text="" />
<TextBlock HorizontalAlignment="Center" Text="Save" />
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</ScrollViewer>
</Grid>
Code for the DateOffset Converter:
public class DateTimeToDateTimeOffsetConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
try
{
if (value is DateTime)
{
DateTime date = (DateTime)value;
return new DateTimeOffset(date);
}
else
return new DateTimeOffset(DateTime.Now);
}
catch (Exception ex)
{
return new DateTimeOffset(DateTime.Now);
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
DateTimeOffset dto = (DateTimeOffset)value;
return dto.DateTime;
}
}
Code for the TimeOffset Converter:
public class DateTimeToTimeSpanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
try
{
if (value is DateTime)
{
DateTime date = (DateTime)value;
return new TimeSpan(date.Ticks);
}
else
return new TimeSpan(DateTime.Now.Ticks);
}
catch (Exception ex)
{
return new TimeSpan(DateTime.Now.Ticks);
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
TimeSpan ts = (TimeSpan)value;
DateTime dt = new DateTime(ts.Ticks);
return dt;
}
}
Given the code where the debugger breaks, the error seems to be on the xaml side and, as I said, removing the date and time pickers, which are the only elements where the binding uses a custom converter, seems to fix it.
What am I missing?
UPDATE
Further testing has brought to my attention that removing the custom converters doesnt actually fix the issue, it just increases the number of navigations until the error happens. I've tried removing the bindings altogether and still got the error. Removing every element but the button that calls the next page seems to work but at this point I can't tell for sure if it actually fixes the issue or just mitigates it.
On a side note, navigating back to the first page using the phone Back button works flawlessly. The error only seems to happen if Frame.GoBack() is explicitly invoked.
These sorts of exceptions don't provide too many hints as to what's causing them, but there are a few things you could try:
I'd remove the ScrollViewer from around lstOrders. It doesn't add any value, yet it could break virtualization of the ListView causing it to try to use arbitrary amounts of memory and CPU if you'd accidentally removed MaxHeight set on the lstOrders.
The btnSave template is bad as it removes interactive feedback elements.
Make sure the properties you bind to are not changed off the UI/Dispatcher thread.
As mentioned in the comments on the question, I have been experiencing this issue today. It was relatively straight forward to isolate the issue to the TimePicker control and, more specifically, the two way binding on the Time property of the control.
However, it was less straight forward to work out why it was happening. It seems to be some issue around visibility (I experience the issue when moving my app to the background) and updating the bound value. Regardless, I tried a variety of things to no avail.
In the end, I tried changing the binding expression from the traditional {Binding} syntax to the compiled {x:Bind} and, fortunately, the problem went away.
Perhaps, give that a shot and see if it solves your problem. Obviously the TimePicker will need to be inside a DataTemplate with a data type specific or - as in my case - a user control with custom dependency properties.

How do I Set height of a grid inside a DataTemplate

The DataTemplate is used in an ItemsControl inside a UserControl. The UserControl is added multiple times inside a stackpanel. (pfew)
I need to be able to determine how many children the stackpanel has. I assumed this was possible using the FindAncestor mode, but I'm afraid I need your help.
Here's the XAML logic:
<StackPanel Name="BeforeTournament" Orientation="Horizontal" VerticalAlignment="Top">
<UserControl ...
<Grid>
<TextBlock Name="txtTitle" FontSize="14" />
<ItemsControl Name="MatchList" ItemsSource="{Binding Matches, Mode=OneWay}" Width="400" Margin="-7,20,0,0"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Name="MatchTemplate" Width="390"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}},
Path=(Children.Count * 300}"
Margin="0,0,0,50" VerticalAlignment="Center">
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
//Duplicates below, same logic to determine width
<UserControl></UserControl>
</StackPanel>
So I would basically like to know how many UserControls have been added to the stackpanel and be able to use this amound of children to calculate the height of the grid inside the DataTemplate.
The FindAncestor relative source is giving me an error saying that Children is not supported in a relative context.
Ok, as I said in the comment there should be a better way to do this, but I'am pretty sure one way to do this is to use a converter. Pass the stackpanel as parameter and return the number of children multiplied by 300(If that is what you want)
I have tried this code and it works. Just for show i added two usercontrols manually. I have also tried putting the usercontrols in a seperate xaml file.
Main.xaml
<Window.Resources>
<local:StackpanelConverter x:Key="StackpanelConverter"/>
</Window.Resources>
<StackPanel Name="BeforeTournament" Orientation="Horizontal" VerticalAlignment="Top">
<UserControl>
<Grid Height="200" Background="Brown">
<TextBlock Name="txtTitle" FontSize="14" />
<ItemsControl Name="MatchList" ItemsSource="{Binding MyControls}" BorderBrush="Bisque" BorderThickness="10" Width="400" Margin="-7,20,0,0"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Name="MatchTemplate" Width="390" Background="Blue"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}}, Converter={StaticResource StackpanelConverter}}"
Margin="0,0,0,50" VerticalAlignment="Center">
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
<UserControl>
<Grid Height="200" Background="Brown">
<TextBlock FontSize="14" />
<ItemsControl ItemsSource="{Binding MyControls}" BorderBrush="Bisque" BorderThickness="10" Width="400" Margin="-7,20,0,0"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Name="MatchTemplate" Width="390" Background="Blue"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}}, Converter={StaticResource StackpanelConverter}}"
Margin="0,0,0,50" VerticalAlignment="Center">
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
</StackPanel>
Example of converter: (this is written in notepad so there might be errors)
public class StackpanelConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var stackpanel = value as StackPanel;
var height = stackpanel.Children.Count;
return height*300;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Tell me if I still don't understand the question :)

show image in tabcontrol tab header if textbox has text WPF

Okay, What I'm trying to accomplish:
A tabheader which gets an image if the textbox inside has text. but if the textbox inside the TabItem doesn't have any text, then the image should not be shown.
this is what I have so far:
----- TAB ITEM CODE -----
<TabItem Name="tabAantekeningen" Header="">
<TabItem.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="8" Text="Aantekeningen"/>
<Image Grid.Column="1" Source="..\Resources\validate.png" Height="20" Width="17"/>
</Grid>
</DataTemplate>
</TabItem.HeaderTemplate>
<TextBox Name="txtOmschrijving" TextWrapping="Wrap" AcceptsReturn="True"></TextBox>
</TabItem>
----- TAB ITEM CODE -----
----- Code Behind -----
public void SetTabItemHeader()
{
if (String.IsNullOrEmpty(txtOmschrijving.Text))
{
tabAantekeningen.Header = "Aantekeningen";
}
}
----- Code Behind -----
IS there a way that I can say: txtOmschrijving.Text == Empty so hide the Image?
Edit: Didn't see your seccond question there, yes there is use a IValueConverter, where you check if the string is empty and Bind To Visibility for instance, so you return Visbility.Collapsed when empty or else Visbility.Visible.
Like this :
public class StringEmptyToVisbililityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value == null) || !(value is string) || string.IsNullOrEmpty(value.ToString()) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Fully working xaml, change your namespaces and URI pack
<Window x:Class="TabItemHeader.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TabItemHeader"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:StringEmptyToVisbililityConverter x:Key="StringEmptyToVisbililityConverter"/>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Name="tabAantekeningen">
<TabItem.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="8" Text="{Binding Path='Header',RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}"/>
<Image Grid.Column="1" Source="pack://application:,,,/TabItemHeader;component/Resources/Images/validate.png" Height="20" Width="17" Visibility="{Binding Path='Header', Converter={StaticResource StringEmptyToVisbililityConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}"/>
</Grid>
</DataTemplate>
</TabItem.HeaderTemplate>
<TextBox Name="txtOmschrijving" TextWrapping="Wrap" AcceptsReturn="True"></TextBox>
</TabItem>
</TabControl>
</Grid>
This will bind to the listboxitem which wraps everything in a listbox. The converter will only show this image when the string is not empty. You can do alot of fun with them :)
WPF cheat sheet is a really handy and compact paper on all types of bindings.
Oh..I am assuming this image will be deployed with your application? Then please ensure that your image is set to resource, you should consider using uri packs as well for your images, an example is in this post as well as the xaml provided. If your image is dynamic, you will have to bind them to some model in an observablecollection.
Tip: I'll stop pushing this to far, but you should consider having a look at the MVVM pattern. I just used code behind my self, so the answer wouldn't get to big. It's whole other topic! =) There are also cleaner ways to either share templates, and change them on types bound in the collection.
Hope it helps.
Cheers,
Stian

trouble with changing an item's property in a listbox

I've created a listbox, to which i can add and delete items dynamically UI changes accordingly and it works fine.
<ListBox Name="MsgsList" ItemsSource="{Binding Items}" Style="{StaticResource MsgsBoxStyle}">
<ListBox.ItemTemplate>
<DataTemplate x:Name="MsgsDataTemplate">
<StackPanel Tag="{Binding MsgTagInfo}" ManipulationCompleted="StackPanel_Msgs_ManipulationCompleted">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Hold="GestureListener_Hold" Tap="GestureListener_Tap"/>
</toolkit:GestureService.GestureListener>
<Grid x:Name="ContentPanelInner" Grid.Row="1" Width="500">
<StackPanel x:Name="stackPanelInner" Width="500">
<Grid VerticalAlignment="Top" Width="500">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding MsgTitle}" Style="{StaticResource MsgLine1}" />
<TextBlock Grid.Column="1" Text="{Binding MsgDate}" Style="{StaticResource MsgDate}" />
</Grid>
<TextBlock Text="{Binding MsgBody}" Style="{StaticResource MsgLine2}" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
but i didn't understand how to change a style for a particular item's textblock, say based on some condition, if i want to change color of specific item's textbox(s), not sure how to access that.
can somebody please help me with this? thanks.
Probably not the easiest way to do this, but arguably the cleanest from a separation of concerns point of view is by using a converter, and binding that to the property you want to monitor...
For example, if your model is changing state based on a boolean property called myProperty, you could use something like this.
<StackPanel Background={Binding myProperty, Converter={StaticResource myBindingConverter}" />
Your converter should return a SolidColorBrush, based on the value of your property.
public class AlternateRowColour : IValueConverter
{
SolidColorBrush normal = new SolidColorBrush(Colors.Transparent);
SolidColorBrush highlighted = new SolidColorBrush(Color.FromArgb(255, 241, 241, 241));
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var myValue = (bool)value
return myValue ? highlighted : normal ;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
I If you just want to change on aspect of an items style, for example its color, you could expose that as property of the model object you are binding. For example, add a property TextColor and bind it as follows:
<TextBlock Text="{Binding MsgBody}" Style="{StaticResource MsgLine2}">
<TextBlock.Color>
<SolidColorBrush Color="{Binding TextColor}"/>
</TextBlock.Color>
</TextBlock>
This will take precedence over the colour defined via the style.

Categories

Resources