I'm trying to bind a property value in a VisualState to a property of the templated FrameworkElement using TemplateBinding but it doesn't work. There are no errors but no results, either. Here's an example of what I tried:
public class ButtonEx : Button
{
public ButtonEx() : base() { }
public static readonly DependencyProperty BackgroundPointerOverProperty = DependencyProperty.Register(
"BackgroundPointerOver", typeof(SolidColorBrush), typeof(ButtonEx), new PropertyMetadata(null));
public SolidColorBrush BackgroundPointerOver
{
get => (SolidColorBrush)GetValue(BackgroundPointerOverProperty);
set => SetValue(BackgroundPointerOverProperty, value);
}
}
The Control Template:
<ControlTemplate TargetType="classes:ButtonEx">
<Grid x:Name="LayoutRoot" >
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{TemplateBinding BackgroundPointerOver}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
Shouldn't the Setter set the ButtonEx background to the value of the parent property on mouse-over? This is in a WinUI 3 Desktop App.
You can make it work binding via RelativeSource.
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=BackgroundPointerOver}" />
</VisualState.Setters>
</VisualState>
Related
I have a basic CollectionView:
<CollectionView x:Name="ItemsList" SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid HeightRequest="80">
<Label Text="Hello world" VerticalOptions="Center"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
public MainPage()
{
InitializeComponent();
ItemsList.ItemsSource = new List<string>() { "1", "2", "3", "4" };
}
On Android, when the item is tapped you will get a simple tap effect:
I want to keep this effect. But if I change the background color according to the documentation:
<ContentPage.Resources>
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="LightSkyBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
The tap effect disappears. Is there some other way to do this?
You can use the Background instead of using the BackgroundColor and the effect will back.
<Setter Property="Background" Value="LightSkyBlue"/>
I have created a bool to color like this:
public class BoolToColorConverter : BindableObject, IValueConverter
{
public BoolToColorConverter()
{
}
public static readonly BindableProperty TrueColorProperty =
BindableProperty.Create(nameof(TrueColor), typeof(Color), typeof(BoolToColorConverter), null, BindingMode.OneWay, null, null);
public Color TrueColor
{
get { return (Color) GetValue(TrueColorProperty); }
set { SetValue(TrueColorProperty, value); }
}
public Color FalseColor { get; set; } = null!;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool b && b)
{
return TrueColor!;
}
return FalseColor!;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
With this I could use AppThemeBinding when I create the converter:
<ContentPage.Resources>
<converts:BoolToColorConverter
x:Key="ColorConverter"
TrueColor="{AppThemeBinding Light=DarkRed, Dark=LightSalmon}"
FalseColor="#888" />
</ContentPage.Resources>
<VerticalStackLayout>
<Label
Text="Hello, World!"
TextColor="{Binding Source={x:Reference Checky}, Path=IsChecked, Converter={StaticResource ColorConverter}}"
FontSize="32"
HorizontalOptions="Center" />
<CheckBox x:Name="Checky" />
</VerticalStackLayout>
This works as expected if the theme is set on start up.
Dark on start:
Ligh on start:
But if the theme is changed when the application is running, the binding is not reevaluated and the old color is shown. Here is how looks like if thmese is changed from dark mode to light:
Is there some workaround for this?
You could use the Visual State Manager instead.
With StateTrigger
This is the easiest solution for this specific scenario. Add this converter:
internal class InvertedBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
return !(bool)value;
}
catch
{
return false;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And then use this XAML:
<ContentPage.Resources>
<converts:InvertedBoolConverter x:Key="InvertedBoolConverter" />
</ContentPage.Resources>
<VerticalStackLayout
x:Name="MainLayout"
Spacing="25"
Padding="30,0">
<Label
Text="Hello, World!"
FontSize="32"
HorizontalOptions="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="Checked state">
<VisualState Name="Checked">
<VisualState.StateTriggers>
<StateTrigger
IsActive="{Binding Source={x:Reference Checky}, Path=IsChecked}"
/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light=DarkRed, Dark=LightSalmon}" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Not checked">
<VisualState.StateTriggers>
<StateTrigger
IsActive="{Binding Source={x:Reference Checky}, Path=IsChecked, Converter={StaticResource InvertedBoolConverter}}"
/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="TextColor" Value="#888" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Label>
<CheckBox x:Name="Checky" />
</VerticalStackLayout>
With custom trigger
In a more complex scenario, you might want to use a customer trigger instead. Sample:
public class BoolTrigger : StateTriggerBase
{
public static readonly BindableProperty
ValueProperty = BindableProperty.Create(nameof(Value), typeof(object), typeof(BoolTrigger), null, propertyChanged: OnBindablePropertyChanged);
public object Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public bool OnValue { get; set; }
private static void OnBindablePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var trigger = bindable as BoolTrigger;
trigger.UpdateTrigger();
}
private void UpdateTrigger()
{
if (Value is not bool val)
{
return;
}
SetActive(OnValue == val);
}
}
And then like this in XAML:
<VerticalStackLayout
x:Name="MainLayout"
Spacing="25"
Padding="30,0">
<Label
Text="Hello, World!"
FontSize="32"
HorizontalOptions="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="Checked state">
<VisualState Name="Checked">
<VisualState.StateTriggers>
<converts:BoolTrigger
OnValue="true"
Value="{Binding Source={x:Reference Checky}, Path=IsChecked}"
/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light=DarkRed, Dark=LightSalmon}" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Not checked">
<VisualState.StateTriggers>
<converts:BoolTrigger
OnValue="false"
Value="{Binding Source={x:Reference Checky}, Path=IsChecked}"
/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="TextColor" Value="#888" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Label>
<CheckBox x:Name="Checky" />
</VerticalStackLayout>
I'm using the Windows Phone 8.1 DatePicker
It's displaying the date as month/day/year by default and I can't see any way to change this to the 'correct' way of day/month/year.
This is how I declare the DatePicker
<DatePicker Name="datePicker" HorizontalAlignment="Center" MonthFormat="{}{month.full}"/>
displaying it as
I can see in the linked msdn article that I can use a DateTimeFormatter in conjunction with ComboBox selectors but that's not an option for me.
Is it possible?
To Edit the Template
In Xaml every control has a style which you can manipulate, to change it's look and feel. Controls also inherit from one another, for example a date picker is made up of a button and a content container. And a button is made up of a border and a content container.
To Update the date pickers style.. Right click on the date picker control in visual studio from the Menu click edit template then click edit a copy. For this example you want to edit the style of the button template with in the date picker Template...
You will also need to create a Converter class to used in the template
This answer worked for me
Page with date picker...
<Page
x:Class="DatePikerAnswer.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DatePikerAnswer"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<!-- Format Converter -->
<local:DateConverter x:Key="FormatConverter"/>
<!-- My Button Style-->
<Thickness x:Key="PhoneBorderThickness">2.5</Thickness>
<FontWeight x:Key="PhoneButtonFontWeight">Semibold</FontWeight>
<x:Double x:Key="TextStyleLargeFontSize">18.14</x:Double>
<x:Double x:Key="PhoneButtonMinHeight">57.5</x:Double>
<x:Double x:Key="PhoneButtonMinWidth">109</x:Double>
<Thickness x:Key="PhoneTouchTargetOverhang">0,9.5</Thickness>
<SolidColorBrush x:Key="ButtonDisabledBackgroundThemeBrush" Color="Transparent"/>
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{ThemeResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}"/>
<Setter Property="FontWeight" Value="{ThemeResource PhoneButtonFontWeight}"/>
<Setter Property="FontSize" Value="{ThemeResource TextStyleLargeFontSize}"/>
<Setter Property="Padding" Value="9.5,0"/>
<Setter Property="MinHeight" Value="{ThemeResource PhoneButtonMinHeight}"/>
<Setter Property="MinWidth" Value="{ThemeResource PhoneButtonMinWidth}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="Grid" Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Pressed" To="PointerOver">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="Grid"/>
</Storyboard>
</VisualTransition>
<VisualTransition From="PointerOver" To="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="Grid"/>
</Storyboard>
</VisualTransition>
<VisualTransition From="Pressed" To="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="Grid"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<PointerDownThemeAnimation Storyboard.TargetName="Grid"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBorderThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{ThemeResource PhoneTouchTargetOverhang}">
<ContentPresenter x:Name="ContentPresenter"
AutomationProperties.AccessibilityView="Raw"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource FormatConverter},ConverterParameter=\{0:dd/MM/yyyy\}}"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--DatePicker Style-->
<FontFamily x:Key="PhoneFontFamilyNormal">Segoe WP</FontFamily>
<x:Double x:Key="ContentControlFontSize">20.26</x:Double>
<Style x:Key="MyDatePickerStyle1" TargetType="DatePicker">
<Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{ThemeResource ContentControlFontSize}"/>
<Setter Property="Foreground" Value="{ThemeResource DatePickerForegroundThemeBrush}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DatePicker">
<StackPanel x:Name="LayoutRoot" Margin="{TemplateBinding Padding}">
<ContentPresenter x:Name="HeaderContentPresenter"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Content="{TemplateBinding Header}" Margin="0,0,0,-3"
Style="{StaticResource HeaderContentPresenterStyle}"/>
<Button x:Name="FlyoutButton"
BorderBrush="{TemplateBinding Foreground}"
BorderThickness="2.5"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
IsEnabled="{TemplateBinding IsEnabled}"
Style="{StaticResource MyButtonStyle}"
Padding="6.5,0,0,3"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid>
</Grid>
</Page>
Converter Class ...
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace DatePikerAnswer
{
class DateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value != null)
{
///Convert Class throws exception so can not convert to date time
string TheCurrentDate = value.ToString();
string[] Values = TheCurrentDate.Split('/');
string Day, Month, Year;
Day = Values[1];
Month = Values[0];
Year = Values[2];
string retvalue = string.Format("{0}/{1}/{2}", Day, Month, Year);
return retvalue;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
The End Result is ...
I needed to show Date as 'Month Year', I tried some solutions I thought about but they didn't work , searched a little and finally found this question and the answer by StuartSmith.
Based on his answer I came up with similar solution that works around localization issue mentioned in comment by Kubaskista
#StuartSmith It will not work for German localization and probably some other regions due to different data format. btw: any idea why "value" in converter is not possible to convert into DateTime?
1- Define Date Picker in xaml, give it name "FirstDatePicker" and then from Designer edit template then choose edit a copy.
<DatePicker x:Name="FirstDatePicker" VerticalAlignment="Top" Grid.Row="1" Margin="0,12,0,0" CalendarIdentifier="GregorianCalendar" DayVisible="False" Padding="0" Style="{StaticResource DatePickerStyle}" RequestedTheme="Light"/>
2- Right Click on FlyoutButton -> Additional Templates -> Edit Generated Content -> Edit a copy.
3- Inside content template, We will bind directly to Date property of FirstDatePicker and by using of StringFormatConverter you can format the date as you wish and override culture also.
<DataTemplate x:Key="DateFormatTemplate">
<Grid>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Date, ConverterParameter=MMMM yyyy, Converter={StaticResource DateFormatConverter}, ElementName=FirstDatePicker, Mode=OneWay}" VerticalAlignment="Top"/>
</Grid>
</DataTemplate>
4- Add StringFormatConverter to solution, Don't forget to add it to resources section of page.
public class DateFormatConverter : IValueConverter
{
#region IValueConverter Members
public object Convert ( object value, Type targetType, object parameter, string language )
{
if(!(value is DateTime || value is DateTimeOffset) || parameter == null) return value;
if(value is DateTime)
{
var date = (DateTime)value;
return date.ToString(parameter.ToString(), CultureInfo.CurrentCulture);
}
else
{
var date = (DateTimeOffset)value;
return date.ToString(parameter.ToString(), CultureInfo.CurrentCulture);
}
}
public object ConvertBack ( object value, Type targetType, object parameter, string language )
{
throw new NotImplementedException();
}
#endregion
}
Note:You can change 'CultureInfo.CurrentCulture' to new Culture("ar-EG") as example or use language passed in converter.
Finally, Here is what i have in resources section of page
<converters:DateFormatConverter x:Key="DateFormatConverter"/>
<x:Double x:Key="ContentControlFontSize">20.26</x:Double>
<FontWeight x:Key="PhoneButtonFontWeight2">Semibold</FontWeight>
<DataTemplate x:Key="DateFormatTemplate">
<Grid>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Date, ConverterParameter=MMMM yyyy, Converter={StaticResource DateFormatConverter}, ElementName=FirstDatePicker, Mode=OneWay}" VerticalAlignment="Top"/>
</Grid>
</DataTemplate>
<Style x:Key="DatePickerStyle" TargetType="DatePicker">
<Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{ThemeResource ContentControlFontSize}"/>
<Setter Property="Foreground" Value="{ThemeResource DatePickerForegroundThemeBrush}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DatePicker">
<StackPanel x:Name="LayoutRoot" Margin="{TemplateBinding Padding}">
<ContentPresenter x:Name="HeaderContentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Margin="0,0,0,-3" Style="{StaticResource HeaderContentPresenterStyle}"/>
<Button x:Name="FlyoutButton" BorderBrush="{TemplateBinding Foreground}" BorderThickness="2.5" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsEnabled="{TemplateBinding IsEnabled}" Padding="12,10" Margin="0" ContentTemplate="{StaticResource DateFormatTemplate}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am experiencing a very weird problem with the WPF Toolkit Charts in a .NET 4 environment.
Basically, I just want to customize the ToolTip template for ColumnDataPoints. To accomplish that, I copied the default style for a ColumnDataPoint from the toolkit source code (generic.xaml) into my control resources and changed the TooltipService part like this:
<UserControl.Resources>
<Style TargetType="charts:ColumnDataPoint" x:Key="CustomDataPointStyle">
<Setter Property="Background" Value="Orange" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="charts:ColumnDataPoint">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Opacity="0" x:Name="Root">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MouseOverHighlight" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectionHighlight" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="RevealStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Shown">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Hidden">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="{TemplateBinding Background}">
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop Color="#77ffffff" Offset="0" />
<GradientStop Color="#00ffffff" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Border BorderBrush="#ccffffff" BorderThickness="1">
<Border BorderBrush="#77ffffff" BorderThickness="1" />
</Border>
<Rectangle x:Name="SelectionHighlight" Fill="Red" Opacity="0" />
<Rectangle x:Name="MouseOverHighlight" Fill="White" Opacity="0" />
</Grid>
<ToolTipService.ToolTip>
<StackPanel>
<ContentControl Content="Custom ToolTip" FontWeight="Bold"/>
<ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
</StackPanel>
</ToolTipService.ToolTip>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now, the problem is that as soon as I apply my CustomDataPointStyle (even if I don't change anything!), the ColumnSeries doesn't show at all in my chart.
<Grid x:Name="ChartGrid" DataContext="{Binding}">
<charts:Chart x:Name="Chart1" Margin="5,0,0,0"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Title="{Binding Path=Title}">
<charts:Chart.Axes>
<charts:CategoryAxis Orientation="X" Title="{Binding Path=XAxisTitle}" Location="Bottom" />
<charts:CategoryAxis Orientation="Y" Title="{Binding Path=YAxisTitle}" Location="Right" ShowGridLines="True" />
</charts:Chart.Axes>
<charts:ColumnSeries x:Name="ColumnSeries" Title="{Binding Path=SeriesTitle}"
ItemsSource="{Binding Path=Data}" DataPointStyle="{StaticResource CustomDataPointStyle}"
DependentValueBinding="{Binding Path=Value}" IndependentValueBinding="{Binding Path=Key}">
</charts:ColumnSeries>
</charts:Chart>
results in this:
I guess that I am missing a VisualState or something that actually renders the chart but how can that be, given that I copied(!) the original style? The Toolkit is made for .NET 3.5 and I have to use .NET 4 in my application - could that be the reason?
Oh dear, I found the answer: I replaced the System.Windows.DataVisualization.Toolkit.dll for .NET 3.5 with the 4.0 version of this one and now it's working!
You could also try setting Opacity="1" in your Border style block:
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Opacity="1" x:Name="Root">
I have a problem with my MVVM Light implementation where I have my WPF Toolkit DataGrid and Data context bound to the correct object but no data is showing up. Can someone tell me what I'm doing wrong?
Here is my code:
MainViewModel.cs
public class MainViewModel : ViewModelBase
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private C.Wsi.ClientSession privateSession;
private ObservableCollection<CashAccount> _cashaccounts;
public ObservableCollection<CashAccount> CashAccounts
{
get { return _cashaccounts; }
set
{
if (_cashaccounts.Equals(value))
{
return;
}
_cashaccounts = value;
RaisePropertyChanged("CashAccounts");
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
_cashaccounts = new ObservableCollection<CashAccount>();
// Subscribe to CollectionChanged event
_cashaccounts.CollectionChanged += OnCashAccountListChanged;
logger.Info("----- Start -----");
// Code runs "for real"
Cs.Helper.Session session = new Session();
privateSession = session.getSession();
logger.Info("Private Session: " + privateSession.GetHashCode());
logger.Info("...Connected.....");
Cs.Helper.ResultSet results = new ResultSet();
PositionBean[] pos = results.getPositions(privateSession);
logger.Info("Positions returned: " + pos.Length);
SecurityBean[] secs = results.getSecurities(privateSession);
logger.Info("Securities returned: " + secs.Length);
ArrayBuilder ab = new ArrayBuilder(pos, secs);
CashAccount c = new CashAccount();
c.qtySod = 100.00;
c.name = "Hi";
c.account = "Acct1";
c.cashAmount = 67.00;
_cashaccounts.Add(c);
RaisePropertyChanged("CashAccounts");
//this._cashaccounts=ab.joinPositionSecurities();
}
}
void OnCashAccountListChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
}
////public override void Cleanup()
////{
//// // Clean up if needed
//// base.Cleanup();
////}
}
MainWindow.xaml
<Window x:Class="CreditSuisse.MainWindow"
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"
xmlns:local="clr-namespace:CreditSuisse.Helper"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
mc:Ignorable="d"
Height="301"
Width="520"
Title="Credit Suisse - Custodial Cash Application"
DataContext="{Binding Path=Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
<local:VisibilityConverter x:Key="VisibilityConverter" />
<!-- DataGrid Background -->
<LinearGradientBrush x:Key="BlueLightGradientBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFEAF3FF"/>
<GradientStop Offset="0.654" Color="#FFC0DEFF"/>
<GradientStop Offset="1" Color="#FFC0D9FB"/>
</LinearGradientBrush>
<!-- DatGrid style -->
<Style TargetType="{x:Type dg:DataGrid}">
<Setter Property="Margin" Value="5" />
<Setter Property="Background" Value="{StaticResource BlueLightGradientBrush}" />
<Setter Property="BorderBrush" Value="#FFA6CCF2" />
<Setter Property="RowBackground" Value="White" />
<Setter Property="AlternatingRowBackground" Value="#FDFFD0" />
<Setter Property="HorizontalGridLinesBrush" Value="Transparent" />
<Setter Property="VerticalGridLinesBrush" Value="#FFD3D0" />
<Setter Property="RowHeaderWidth" Value="0" />
</Style>
<!-- Enable rows as drop targets -->
<Style TargetType="{x:Type dg:DataGridRow}">
<Setter Property="AllowDrop" Value="True" />
</Style>
</ResourceDictionary>
</Window.Resources>
<dg:DataGrid DataContext="{Binding MainViewModel}" ItemsSource="{Binding CashAccounts}">
Margin="5" AutoGenerateColumns="True" HorizontalScrollBarVisibility="False">
<dg:DataGrid.Columns>
<dg:DataGridTextColumn Binding="{Binding account}" Header="Account Code" />
<dg:DataGridTextColumn Binding="{Binding name}" Header="Security Name" />
<dg:DataGridTextColumn Binding="{Binding cashAmount}" Header="Quantity Start of Day" />
<dg:DataGridTextColumn Binding="{Binding price}" Header="Cash Delta (Price Delta)" />
<dg:DataGridTemplateColumn Header="Action">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Get" Visibility="{Binding cashChanged, Converter={StaticResource VisibilityConverter}}" Background="Red" />
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
</dg:DataGrid.Columns>
</dg:DataGrid>
When you do DataContext="{Binding Path=Main, Source={StaticResource Locator}}" in your Window and after DataContext="{Binding MainViewModel}" in the Datagrid, WPF tries to bind to a property named MainViewModel on your MainViewModel class which will fail. You can confirm this by looking for the binding error in the Output window in VS.
Just remove DataContext="{Binding MainViewModel}" from the DataGrid and it should work.
EDIT:
There is an extra closing > at the end of the first line in your XAML:
<dg:DataGrid DataContext="{Binding MainViewModel}" ItemsSource="{Binding CashAccounts}">
Margin="5" AutoGenerateColumns="True" HorizontalScrollBarVisibility="False">
It should be:
<dg:DataGrid DataContext="{Binding MainViewModel}" ItemsSource="{Binding CashAccounts}"
Margin="5" AutoGenerateColumns="True" HorizontalScrollBarVisibility="Disabled">
Note: False is not a valid value for HorizontalScrollBarVisibility it supports Auto, Disabled, Hidden, Visible
But I don't know why WPF throws Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead for your original XAML instead of some more meaningful error.