Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/TestApp/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
<local:SampleContainer Title="IsNullOrEmptyStateTrigger">
<samples:IsNullOrEmptySample />
</local:SampleContainer>

<local:SampleContainer Title="InverseTrigger">
<samples:InverseSample />
</local:SampleContainer>

<local:SampleContainer Title="IsTypePresentStateTrigger">
<samples:IsTypePresentSample />
Expand Down
114 changes: 114 additions & 0 deletions src/TestApp/Samples/InverseSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<UserControl x:Class="TestApp.Samples.InverseSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp.Samples"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:triggers="using:WindowsStateTriggers"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="textboxstates">
<VisualState x:Name="textboxnotemptystate">
<VisualState.StateTriggers>
<triggers:InverseTrigger>
<triggers:InverseTrigger.StateTrigger>
<triggers:IsNullOrEmptyStateTrigger Value="{x:Bind textbox.Text, Mode=OneWay}" />
</triggers:InverseTrigger.StateTrigger>
</triggers:InverseTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="textbox.BorderBrush"
Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="textboxemptystate">
<VisualState.StateTriggers>
<triggers:IsNullOrEmptyStateTrigger Value="{x:Bind textbox.Text, Mode=OneWay}" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="textbox.Background"
Value="BlanchedAlmond" />
<Setter Target="textbox.BorderBrush"
Value="Red" />
<Setter Target="textboxError.Visibility"
Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="listboxstates">
<VisualState x:Name="listnotemptystate">
<VisualState.StateTriggers>
<triggers:InverseTrigger>
<triggers:InverseTrigger.StateTrigger>
<triggers:IsNullOrEmptyStateTrigger Value="{x:Bind list.Items, Mode=OneWay}" />
</triggers:InverseTrigger.StateTrigger>
</triggers:InverseTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="list.Visibility"
Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="listemptystate">
<VisualState.StateTriggers>
<triggers:IsNullOrEmptyStateTrigger Value="{x:Bind list.Items, Mode=OneWay}" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="remove.IsEnabled"
Value="False" />
<Setter Target="listEmptyMessage.Visibility"
Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="The TextBox will be green if not empty." />
<StackPanel Orientation="Horizontal"
Margin="0 0 0 20">
<TextBox x:Name="textbox"
Text=""
Width="200" />
<TextBlock x:Name="textboxError"
Text="* Required"
Foreground="Red"
Margin="10 0 0 0"
Visibility="Collapsed" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="add"
Content="Add"
Margin="0 0 10 0"
Click="add_Click" />
<Button x:Name="remove"
Content="Remove"
Click="remove_Click" />
</StackPanel>
<TextBlock x:Name="listEmptyMessage"
Text="List is empty, add some items"
Visibility="Collapsed" />
<ListBox x:Name="list"
HorizontalAlignment="Left"
Visibility="Collapsed">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding"
Value="3" />
<Setter Property="Margin"
Value="3" />
<Setter Property="Background"
Value="Red" />
<Setter Property="Foreground"
Value="White" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</StackPanel>
</Grid>
</UserControl>
31 changes: 31 additions & 0 deletions src/TestApp/Samples/InverseSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace TestApp.Samples
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class InverseSample : UserControl
{
public InverseSample()
{
this.InitializeComponent();
}

private void add_Click(object sender, RoutedEventArgs e)
{
list.Items.Add("Item");
}

private void remove_Click(object sender, RoutedEventArgs e)
{
list.Items.RemoveAt(0);
}
}
}
9 changes: 7 additions & 2 deletions src/TestApp/Samples/IsNullOrEmptySample.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@
<VisualStateManager.VisualStateGroups>

<VisualStateGroup x:Name="textboxstates">
<VisualState x:Name="textboxnotemptystate" />
<VisualState x:Name="textboxemptystate">
<VisualState x:Name="textboxnotemptystate">
<VisualState.Setters>
<Setter Target="textbox.BorderBrush"
Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="textboxemptystate">
<VisualState.StateTriggers>
<triggers:IsNullOrEmptyStateTrigger Value="{x:Bind textbox.Text, Mode=OneWay}"/>
</VisualState.StateTriggers>
Expand Down
7 changes: 7 additions & 0 deletions src/TestApp/TestApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@
<Compile Include="Samples\IsHostedSample.xaml.cs">
<DependentUpon>IsHostedSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\InverseSample.xaml.cs">
<DependentUpon>InverseSample.xaml</DependentUpon>
</Compile>
<Compile Include="Samples\IsNullOrEmptySample.xaml.cs">
<DependentUpon>IsNullOrEmptySample.xaml</DependentUpon>
</Compile>
Expand Down Expand Up @@ -186,6 +189,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\InverseSample.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Samples\IsNullOrEmptySample.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand Down
81 changes: 81 additions & 0 deletions src/WindowsStateTriggers/InverseTrigger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) Morten Nielsen. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Xaml;

namespace WindowsStateTriggers
{
/// <summary>
/// Inverts another State Trigger that is using ITriggerValue
/// </summary>
public class InverseTrigger : StateTriggerBase, ITriggerValue
{
/// <summary>
/// Gets or sets the State Trigger to invert.
/// </summary>
public ITriggerValue StateTrigger
{
get { return (ITriggerValue)GetValue(StateTriggerProperty); }
set { SetValue(StateTriggerProperty, value); }
}

/// <summary>
/// Identifies the <see cref="StateTrigger"/> DependencyProperty
/// </summary>
public static readonly DependencyProperty StateTriggerProperty =
DependencyProperty.Register("StateTrigger", typeof(ITriggerValue), typeof(InverseTrigger),
new PropertyMetadata(null, OnStateTriggerPropertyChanged));

private static void OnStateTriggerPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = (InverseTrigger)d;
var val = (ITriggerValue)e.NewValue;
if (val != null)
{
obj.IsActive = !val.IsActive;
WeakEventListener<ITriggerValue, object, EventArgs> weakEvent = new WeakEventListener<ITriggerValue, object, EventArgs>(val)
{
OnEventAction = (instance, source, args) => obj.IsActive = !instance.IsActive,
OnDetachAction = (instance, weakEventListener) => instance.IsActiveChanged -= weakEventListener.OnEvent
};
val.IsActiveChanged += weakEvent.OnEvent;
}
else
{
obj.IsActive = false;
}
}
#region ITriggerValue

private bool m_IsActive;

/// <summary>
/// Gets a value indicating whether this trigger is active.
/// </summary>
/// <value><c>true</c> if this trigger is active; otherwise, <c>false</c>.</value>
public bool IsActive
{
get { return m_IsActive; }
private set
{
if (m_IsActive != value)
{
m_IsActive = value;
base.SetActive(value);
if (IsActiveChanged != null)
IsActiveChanged(this, EventArgs.Empty);
}
}
}

/// <summary>
/// Occurs when the <see cref="IsActive" /> property has changed.
/// </summary>
public event EventHandler IsActiveChanged;

#endregion ITriggerValue
}
}
1 change: 1 addition & 0 deletions src/WindowsStateTriggers/WindowsStateTriggers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<Compile Include="CompositeStateTrigger.cs" />
<Compile Include="FullScreenModeTrigger.cs" />
<Compile Include="HostedStateTrigger.cs" />
<Compile Include="InverseTrigger.cs" />
<Compile Include="UserHandPreferenceStateTrigger.cs" />
<Compile Include="RegexStateTrigger.cs" />
<Compile Include="InputTypeTrigger.cs" />
Expand Down