2013-07-17 3 views
3

Я хочу создать окно, похожее на экран Android, показывающий состояние bluetooth, wifi ..etc. У меня есть класс, который проверяет состояние указанного устройства и возвращает значение байта 0 для off, 1 для включения и 0xFF для ошибки. Затем я сделал кнопку (вероятно, должно быть ToggleButton..but я новичок в 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)); 
} 

примечание о том, что класс выше, что я имею в виду, что я не хочу свойство зависимостей? ? Вместо этого я предпочел бы установить значение, а цвет фона изменится на соответствующий цвет. 0 будет серым, 1 будет зеленым> 1 будет красным. Одна вещь, которую я не знаю, как сделать

Затем я создал UserControl для Bluetooth и затем изменил тип на ToggleTaskButton. Проект это просто библиотека классов, поэтому я не получаю словарь ресурсов:/Я пытался получить правильную работу кнопки, прежде чем я разместил ее. Извините за беспорядок.

<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> 

КОД ЗА

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(); 
     } 
    } 
} 

Так что я в конечном итоге на самом деле не знаю, что я делаю. Я хочу, чтобы это WPF из-за большого количества планшетов и различных размеров экрана, с которыми я сталкиваюсь. Я думаю, что в OnLoad элемент управления должен использовать задачу Bluetooth для установки состояния. Когда состояние устанавливается, оно меняет цвет моей второй градиентной остановки на фоне границы. Пожалуйста помоги. Как установить цвет GradientStop? И когда я добавить этот элемент управления в UserControl в приложении WPF он ничего не показывает, но в моем конструкторе он показывает один из этих 3-х кнопок

enter image description here

+0

@JoeKorolewicz Благодарим Вас за добавление этого тега. –

+0

В prinitsipe может быть проще, например, с помощью 'Dependency Property' или' Visual State Manager'. Вам нужно альтернативное решение вашей проблемы? Или вы хотите делать то, что вы написали? –

+0

@ AnatoliyNikolaev Я надеюсь на решение моей проблемы. Я до сих пор не понял, как правильно делать эту работу, но я думаю, что я становлюсь немного ближе. –

ответ

1

я создал пример со свойством прикрепленной зависимости CurrentStatus, который содержит текущий статус соединения. Я также создал шаблон для триггеров Button, которые устанавливают свойства для Button, в зависимости от состояния. На Button может быть три состояния, и добавить новое состояние не сложно.

Пример стиля кнопки:

<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> 

Здесь DataTrigger устанавливает значение статуса:

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:DepClass.CurrentStatus)}" Value="1"> 
    <Setter Property="Background" Value="Green" /> 
</DataTrigger> 

Триггер также может выглядеть следующим образом:

<Trigger Property="local:DepClass.CurrentStatus" Value="1"> 
    <Setter Property="Background" Value="#E59400" />        
</Trigger> 

Это будет тоже самое.

Output

Статус 0:

enter image description here

Статус 1:

enter image description here

Статус 2:

enter image description here

Листинг 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); 
    }   
} 

Статус определяется следующим образом:

DepClass.SetCurrentStatus(BluetoothButton, 1); 

Или в XAML как это:

<Button local:DepClass.CurrentStatus="0" ... /> 

Полный пример:

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); 
    }   
} 
+1

WOW! Я так поражен этим. Надеюсь, вам не пришлось долго тратить на это безумное время. Как только я получу это, и он работает, я, скорее всего, приму ваш ответ, потому что он выглядит именно так, как я и искал. Большое спасибо. –

+0

Добро пожаловать :). –

+0

@Robert Snyder: У вас нет проблем с примером? Это может быть что-то объяснить? –