Reputation: 2409
I want to make a window similar to the Android screen that shows the state of bluetooth, wifi..etc. I have a class that checks the state of said device and returns a byte value of 0 for off, 1 for on and 0xFF for error. I then made a Button (probably should be ToggleButton..but i'm very new to WPF)
public class ToggleTaskButton : System.Windows.Controls.Primitives.ButtonBase
{
public ImageSource ImageSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
public Color MyBackgroundColor
{
get { return (Color)GetValue(MyBackgroundColorProperty); }
set { SetValue(MyBackgroundColorProperty, value); }
}
// Using a DependencyProperty as the backing store for MyBackgroundColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyBackgroundColorProperty =
DependencyProperty.Register("MyBackgroundColor", typeof(Color), typeof(ToggleTaskButton), new PropertyMetadata(null));
// Using a DependencyProperty as the backing store for ImageSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ToggleTaskButton), new UIPropertyMetadata(null));
}
A note about that class above is that I'm thinking that I don't want a dependency property?? Instead I would rather set a value and the background color changes to the appropriate color. 0 would be gray, 1 would be green >1 would be red. One thing I don't know how to do
I then made a Bluetooth UserControl and then changed the type to ToggleTaskButton. The project this is just a Class Library, so I don't get a resource dictionary :/ I was trying to get the button click portion to work correctly before I posted this. Sorry for the mess.
<ata:ToggleTaskButton x:Class="AdvancedTaskAssigner.Controls.BluetoothControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ata="clr-namespace:AdvancedTaskAssigner.Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Loaded="UserControl_Loaded" Click="ToggleTaskButton_Click"
ImageSource="/AdvancedTaskAssigner;component/Resources/Bluetooth.png" MyBackgroundColor="Green">
<ata:ToggleTaskButton.Resources>
<Style TargetType="{x:Type ata:ToggleTaskButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ata:ToggleTaskButton}">
<Viewbox>
<Grid>
<Border BorderBrush="#FF58595B" BorderThickness="15,15,15,15" CornerRadius="8,8,8,8" >
<Border.Background>
<RadialGradientBrush>
<GradientStop Color="#FFB2B2B2" Offset=".75"/>
<GradientStop Offset="1" Color="#FFB2B2B2" />
</RadialGradientBrush>
</Border.Background>
<Viewbox>
<Image Margin="25" Height="100" Width="100" Source="{TemplateBinding ImageSource}" />
</Viewbox>
</Border>
</Grid>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ata:ToggleTaskButton.Resources>
</ata:ToggleTaskButton>
CODE BEHIND
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace AdvancedTaskAssigner.Controls
{
/// <summary>
/// Interaction logic for BluetoothControl.xaml
/// </summary>
public partial class BluetoothControl : ToggleTaskButton
{
public BluetoothControl()
{
InitializeComponent();
task = new BrightnessTask();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
CheckBluetoothState();
System.Console.Beep(1000, 100);
}
private void CheckBluetoothState()
{
//bluetoothState = ((byte)task.GetState() == 0x01);
//Color c = bluetoothState ? (Color)FindResource("enabledColor") : (Color)FindResource("disabledColor");
//this.outsideColor.Color = c;
}
private BrightnessTask task;
private bool bluetoothState = false;
private void ToggleTaskButton_Click(object sender, RoutedEventArgs e)
{
if (bluetoothState) { task.PerformTaskDown(); MessageBox.Show("BOO"); System.Console.Beep(1000, 100); } //if bluetooth enabled..disable
else { task.PerformTaskUp(); System.Console.Beep(2000, 100); MessageBox.Show("BOO"); }//if bluetooth disabled..enable.
CheckBluetoothState();
}
}
}
So I end up not really know what I am doing. I want this to be WPF because of the wide array of tablets and various screen sizes I'm giong to deal with. I'm thinking that OnLoad the control should use the bluetooth task to set the State. When the state gets set it changes the color of my second gradient stop on the Border Background. Please help. How do I set the GradientStop's color? And when I add this control to a UserControl in a WPF application it shows nothing, but in my designer it shows one of these 3 buttons
Upvotes: 3
Views: 589
Reputation: 22702
I created an example with a attached dependency property CurrentStatus
, which contains the current status of the connection. I also created a template for the Button
triggers that set the properties for the Button
, depending on the state. At the Button
can have three states, and add a new state is not difficult.
Example of Button style:
<Style x:Key="BlueToothButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Gainsboro" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="15" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="2" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
<Path x:Name="Bicon" Width="15" Height="27" Stretch="Fill" Fill="#FF000000" Data="F1 M 51,47L 36,61L 36,43L 28.25,50L 25.25,46.75L 35,38L 25.25,29.25L 28.25,26L 36,32L 36,14L 51,29L 42,38L 51,47 Z M 41,43L 41,50.5L 44.5,46.5L 41,43 Z M 41,33L 44.5,29.5L 41,25.3995L 41,33 Z "/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:DepClass.CurrentStatus)}" Value="1">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:DepClass.CurrentStatus)}" Value="2">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E59400" />
<Setter TargetName="Bicon" Property="Fill" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here DataTrigger
sets the value for the status:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:DepClass.CurrentStatus)}" Value="1">
<Setter Property="Background" Value="Green" />
</DataTrigger>
The trigger can also look like this:
<Trigger Property="local:DepClass.CurrentStatus" Value="1">
<Setter Property="Background" Value="#E59400" />
</Trigger>
This will be the same.
Output
Status 0
:
Status 1
:
Status 2
:
Listing of DependencyProperty
:
public class DepClass : DependencyObject
{
public static readonly DependencyProperty CurrentStatusProperty;
public static void SetCurrentStatus(DependencyObject DepObject, int value)
{
DepObject.SetValue(CurrentStatusProperty, value);
}
public static int GetCurrentStatus(DependencyObject DepObject)
{
return (int)DepObject.GetValue(CurrentStatusProperty);
}
static DepClass()
{
PropertyMetadata MyPropertyMetadata = new PropertyMetadata(0);
CurrentStatusProperty = DependencyProperty.RegisterAttached("CurrentStatus",
typeof(int),
typeof(DepClass),
MyPropertyMetadata);
}
}
Status is defined this way:
DepClass.SetCurrentStatus(BluetoothButton, 1);
Or in the XAML like this:
<Button local:DepClass.CurrentStatus="0" ... />
Complete example:
XAML
<Window x:Class="BluetoothButtonHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BluetoothButtonHelp"
Title="MainWindow" Height="350" Width="525"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<Style x:Key="BlueToothButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Gainsboro" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="15" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="2" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
<Path x:Name="Bicon" Width="15" Height="27" Stretch="Fill" Fill="#FF000000" Data="F1 M 51,47L 36,61L 36,43L 28.25,50L 25.25,46.75L 35,38L 25.25,29.25L 28.25,26L 36,32L 36,14L 51,29L 42,38L 51,47 Z M 41,43L 41,50.5L 44.5,46.5L 41,43 Z M 41,33L 44.5,29.5L 41,25.3995L 41,33 Z "/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:DepClass.CurrentStatus)}" Value="1">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:DepClass.CurrentStatus)}" Value="2">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E59400" />
<Setter TargetName="Bicon" Property="Fill" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Name="BluetoothButton" Style="{StaticResource BlueToothButtonStyle}" local:DepClass.CurrentStatus="0" Width="40" Height="40" />
<Button Name="Status1" Content="Status 1" Width="100" Height="30" HorizontalAlignment="Left" Click="Status1_Click" />
<Button Name="Status2" Content="Status 2" Width="100" Height="30" HorizontalAlignment="Right" Click="Status2_Click" />
<Button Name="Status0" Content="Status 0" Width="100" Height="30" VerticalAlignment="Top" Click="Status0_Click" />
</Grid>
</Window>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Status1_Click(object sender, RoutedEventArgs e)
{
DepClass.SetCurrentStatus(BluetoothButton, 1);
}
private void Status2_Click(object sender, RoutedEventArgs e)
{
DepClass.SetCurrentStatus(BluetoothButton, 2);
}
private void Status0_Click(object sender, RoutedEventArgs e)
{
DepClass.SetCurrentStatus(BluetoothButton, 0);
}
}
public class DepClass : DependencyObject
{
public static readonly DependencyProperty CurrentStatusProperty;
public static void SetCurrentStatus(DependencyObject DepObject, int value)
{
DepObject.SetValue(CurrentStatusProperty, value);
}
public static int GetCurrentStatus(DependencyObject DepObject)
{
return (int)DepObject.GetValue(CurrentStatusProperty);
}
static DepClass()
{
PropertyMetadata MyPropertyMetadata = new PropertyMetadata(0);
CurrentStatusProperty = DependencyProperty.RegisterAttached("CurrentStatus",
typeof(int),
typeof(DepClass),
MyPropertyMetadata);
}
}
Upvotes: 1