Skip to content
This repository has been archived by the owner on May 8, 2022. It is now read-only.

Commit

Permalink
Merge pull request dotMorten#2 from MagooChris/master
Browse files Browse the repository at this point in the history
Added InverseTrigger and matching sample (by MagooChris)
  • Loading branch information
fsclientdev committed Feb 23, 2019
2 parents 3a97a7a + 5805670 commit b841da5
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 2 deletions.
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

0 comments on commit b841da5

Please sign in to comment.