wpf 学习笔记

1. 同时加载两个窗体

先添加一个子窗体,然后再app.xaml.cs里重写OnStartup方法

//app.xaml.cs

using System.Configuration;
using System.Data;
using System.Windows;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            subWindow sb = new subWindow(); //这是子窗口
            sb.Show();
        }
    }
    
}

参考链接:WPF一次性开启两个窗口 - 夜落璇玑 - 博客园 (cnblogs.com)

2.实现点击窗口任意位置拖动

1、注册3个事件如下: 

// xaml里
<Window PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown"
        PreviewMouseMove="Window_PreviewMouseMove"
        PreviewMouseLeftButtonUp="Window_PreviewMouseLeftButtonUp"/>

//cs里

public partial class subWindow : Window
{
   //定义2个变量记录信息
    Point _pressedPosition;
    bool _isDragMoved = false;

    public subWindow()
    {
        InitializeComponent();
    }

   //记录鼠标按下位置
    void Window_PreviewMouseLeftButtonDown(object sender, 
           System.Windows.Input.MouseButtonEventArgs e)
    {
        _pressedPosition = e.GetPosition(this);
    }

  //鼠标移动触发拖动
    void Window_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (Mouse.LeftButton == MouseButtonState.Pressed && _pressedPosition != e.GetPosition(this))
        {
            _isDragMoved = true;
            DragMove();
        }
    }

 //鼠标弹起屏蔽消息
    void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (_isDragMoved)
        {
            _isDragMoved = false;
            e.Handled = true;
        }
    }
}

参考链接:c# wpf 实现窗口任意区域点击拖动_wpf 拖动窗体-CSDN博客

 3.实现一个透明、无边框、鼠标穿透的WPF窗体

参考链接:Simple WPF:实现一个透明、无边框、鼠标穿透的WPF窗体 - 知乎 (zhihu.com)

一步一步实现WPF透明化窗口_wpf透明窗体-CSDN博客

//设置 AllowsTransparency="True" WindowStyle="None" Background="Transparent"
<Window x:Class="WpfApp1.subWindow"
        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"
        PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown"
        PreviewMouseMove="Window_PreviewMouseMove"
        PreviewMouseLeftButtonUp="Window_PreviewMouseLeftButtonUp"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="subWindow" Height="500" Width="700" AllowsTransparency="True" WindowStyle="None" Background="Transparent">

4.去除标题栏

//设置 WindowStyle ="None"

<Window x:Class="NonFrameWindow.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:NonFrameWindow"
        mc:Ignorable="d"
        WindowStyle ="None" ResizeMode="CanMinimize"
        Title="MainWindow" Height="450" Width="800">

 5.按钮渐变色  鼠标悬停时按钮不变色  控件重叠

 <Window.Resources>
    //设置grid的背景色
     <Style TargetType="Grid" x:Key="ggrid">
         <Setter Property="Background" Value="#F5F7F6F6"></Setter>
     </Style>

     <!--按钮渐变色-->
     <LinearGradientBrush x:Key="Brush2" StartPoint="0,0" EndPoint="0,1">
         <LinearGradientBrush.GradientStops>
             <GradientStop Offset="0" Color="#FF03A795" />
             <GradientStop Offset="1" Color="#FF03786B" />
         </LinearGradientBrush.GradientStops>
     </LinearGradientBrush>
     <LinearGradientBrush x:Key="Brush3" StartPoint="0,0" EndPoint="0,1">
         <LinearGradientBrush.GradientStops>
             <GradientStop Offset="0" Color="#FF03A795" />
             <GradientStop Offset="1" Color="#FF03786B" />
         </LinearGradientBrush.GradientStops>
     </LinearGradientBrush>

   <!--button鼠标悬停时不变色-->
     <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
         <Setter Property="Template">
             <Setter.Value>
                 <ControlTemplate TargetType="{x:Type Button}">
                     <Border Background="{TemplateBinding Background}">
                         <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                     </Border>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
         <Style.Triggers>
             <Trigger Property="IsMouseOver" Value="True">
                 <Setter Property="Background" Value="{x:Null}"/>
             </Trigger>
         </Style.Triggers>
     </Style>
 </Window.Resources>


//调用

<Button Width="130" Height="50" Margin="5" Background="Transparent" BorderThickness="0,0,0,0" Style="{DynamicResource ButtonStyle}">
    <Canvas>
        <Border BorderThickness="2" Canvas.Left="-17" Canvas.Top="-14" Background="{StaticResource Brush3}" CornerRadius="4" Height="35" Width="80">
       //border的渐变色
            <Border.BorderBrush>
                <RadialGradientBrush>
                    <GradientStop Color="Black"/>
                    <GradientStop Color="#FFCCCBCC" Offset="1"/>
                </RadialGradientBrush>
            </Border.BorderBrush>
            <Label Content="123" FontSize="14" Margin="11,1,15,0" />
        </Border>
        <Border BorderThickness="2" Canvas.Left="-50" Canvas.Top="-17"  Background="{StaticResource Brush2}" CornerRadius="18" Height="42" MinWidth="25">
            <Border.BorderBrush>
                <RadialGradientBrush>
                    <GradientStop Color="Black"/>
                    <GradientStop Color="#FFCCCBCC" Offset="1"/>
                </RadialGradientBrush>
            </Border.BorderBrush>
            <Label Content="12" FontSize="14" HorizontalContentAlignment="Center" Margin="0,4,0,0" MinWidth="40"></Label>
        </Border>
    </Canvas>
</Button>

6. grid 分割线(圆角)

  //圆角
<Border CornerRadius="15"  BorderThickness="2" Margin="2,0,2,0" Background="#F7F7F7">
    <Grid>
        <Border>
        </Border>
    </Grid>
</Border>



     <Grid.RowDefinitions>
           <RowDefinition Height="9*"/>
           <RowDefinition Height="9*"/>
           <RowDefinition Height="12*"/>
           <RowDefinition Height="12*"/>
           <RowDefinition Height="24*"/>
           <RowDefinition Height="3*"/>
       </Grid.RowDefinitions>
       <Rectangle Stroke="#FF6F6D6D"  Grid.Row="1"/>
       <Rectangle Stroke="#FF6F6D6D"  Grid.Row="2"/>
       <Rectangle Stroke="#FF6F6D6D" Grid.Row="3"/>
       <Rectangle Stroke="#FF6F6D6D" Grid.Row="4"/>
       <Rectangle Stroke="#FF6F6D6D" Grid.Row="5"/>

 7. textblock 样式(渐变色 )

<TextBlock VerticalAlignment="Bottom"  HorizontalAlignment="Left" FontSize="25" FontWeight="Black" Cursor="AppStarting" Height="30">
    <TextBlock.Style>
        <Style  TargetType="{x:Type TextBlock}">
            <Setter Property="Foreground">
                <Setter.Value>
                    <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,0.5">
                        <GradientStop Color="#FF87E1FF" Offset="0.0" />
                        <GradientStop Color="#FF009FFF" Offset="0.5" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Style>
 </TextBlock.Style><Run Text="抢答器专家"/>
</TextBlock>

//设置字体颜色
 <TextBlock Foreground="#FF03786B">加分</TextBlock>

8.textbox 样式(圆角)

<TextBox VerticalAlignment="Center" HorizontalAlignment="Center" Height="30" Width="60" >
    <TextBox.Resources>
        <Style TargetType="{x:Type Border}">
            <Setter Property="CornerRadius" Value="2"/>
            <Setter Property="BorderBrush" Value="#c1d0dc"/>
        </Style>
    </TextBox.Resources>
</TextBox>


第二种写法:
  <Style TargetType="TextBox">
      <Style.Resources>
          <Style TargetType="{x:Type Border}">
              <Setter Property="CornerRadius" Value="5"/>
              <Setter Property="BorderBrush" Value="#c1d0dc"/>
          </Style>
      </Style.Resources>
  </Style>

9.button

//设置圆角
<Button.Resources>
    <Style TargetType="{x:Type Border}">
        <Setter Property="CornerRadius" Value="3"></Setter>
    </Style>
</Button.Resources>

//设置阴影
 <Button.Effect>
     <DropShadowEffect BlurRadius="20" ShadowDepth="0" Color="#DADADA" Opacity="0.2"/>
 </Button.Effect>


<Style TargetType="{x:Type Button}">
    <Setter Property="Foreground" Value="#FF333333"></Setter>
    <Setter Property="BorderBrush" Value="#33000000"></Setter>
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
                <GradientStop Color="#FFFEFEFE" Offset="0.0"/>
                <GradientStop Color="#FFF5F5F5" Offset="0.5" />
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Foreground" Value="Black"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border Background="{StaticResource background}" BorderThickness="1" BorderBrush="#33000000">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <!--<Setter Property="Background" Value="{StaticResource Brush2}"></Setter>-->
        </Trigger>
        <Trigger Property="IsMouseOver" Value="False">
            <Setter Property="Foreground" Value="#0E867F"></Setter>
        </Trigger>
    </Style.Triggers>
    <Style.Resources>
        <Style TargetType="{x:Type Border}">
            <Setter Property="CornerRadius" Value="4"></Setter>
        </Style>
    </Style.Resources>
</Style>

10.ComboBox(样式)

xaml:
//圆角
<Style  TargetType="{x:Type ComboBox}">
    <Setter Property="Margin" Value="5"></Setter>
    <Setter Property="Width" Value="120"></Setter>
    <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBox}">
                <Border  BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Background="Transparent">
                    <Grid>
                        <!--下拉箭头-->
                        <ToggleButton ClickMode="Press" Focusable="False" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="2" MinWidth="0" MinHeight="0" Width="Auto">
                            <ToggleButton.Style>
                                <Style TargetType="{x:Type ToggleButton}">
                                    <Setter Property="MinWidth" Value="0"/>
                                    <Setter Property="MinHeight" Value="0"/>
                                    <Setter Property="Width" Value="Auto"/>
                                    <Setter Property="Height" Value="Auto"/>
                                    <Setter Property="Background" Value="Transparent"/>
                                    <Setter Property="BorderBrush" Value="#00000000"/>
                                    <Setter Property="BorderThickness" Value="2"/>
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="{x:Type ToggleButton}">
                                                <DockPanel Background="{TemplateBinding Background}" LastChildFill="False" SnapsToDevicePixels="True">
                                                    <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"  DockPanel.Dock="Right" >
                                                        <Path Data="M0,0L3.5,4 7,0z" Fill="{TemplateBinding Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                                    </Border>
                                                </DockPanel>
                                                <ControlTemplate.Triggers>
                                                    <Trigger Property="IsChecked" Value="True">

                                                    </Trigger>
                                                </ControlTemplate.Triggers>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                    <Style.Triggers>
                                        <Trigger Property="IsEnabled" Value="False">
                                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </ToggleButton.Style>
                        </ToggleButton>
                        <!--项内容-->
                        <ContentPresenter  IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" VerticalAlignment="Center" Margin="3" HorizontalAlignment="Stretch" />
                        <TextBox x:Name="PART_EditableTextBox" HorizontalAlignment="Stretch" Focusable="True" Visibility="Collapsed" IsReadOnly="False"/>
                        <!--下拉显示面板HorizontalOffset:设置下拉面板的相对位置-->
                        <Popup HorizontalOffset="-1" Width="{TemplateBinding ActualWidth}"
                               IsOpen="{TemplateBinding IsDropDownOpen}" Focusable="False"    PopupAnimation="Slide">
                            <Grid  SnapsToDevicePixels="True" HorizontalAlignment="Stretch">
                                <Border  BorderThickness="1,1,1,1" BorderBrush="Gray" HorizontalAlignment="Stretch" CornerRadius="5">
                                    <Border.Background>
                                        <SolidColorBrush Color="White" />
                                    </Border.Background>
                                </Border>
                                <ScrollViewer  SnapsToDevicePixels="True" HorizontalAlignment="Stretch" >
                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" HorizontalAlignment="Stretch" />
                                </ScrollViewer>
                            </Grid>
                        </Popup>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>



<ComboBox Width="80" SelectionChanged="ComboBox_SelectionChanged">
    <ComboBoxItem IsSelected="True">0</ComboBoxItem>
    <ComboBoxItem>5</ComboBoxItem>
    <ComboBoxItem>10</ComboBoxItem>
    <ComboBoxItem>20</ComboBoxItem>
</ComboBox>

//允许编辑  设置IsEditable="True",即前面变成文本框形式
<ComboBox x:Name="AddScoreCombox" Width="80" IsEditable="True">
    <ComboBoxItem>0</ComboBoxItem>
    <ComboBoxItem>10</ComboBoxItem>
    <ComboBoxItem>11</ComboBoxItem>
    <ComboBoxItem IsSelected="True">19</ComboBoxItem>
</ComboBox>




cs:
 private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
     int count = Convert.ToInt32(combobox.SelectedValue.ToString().Replace("System.Windows.Controls.ComboBoxItem: ", ""));
    
     SubWindow subWindow = SubWindow.pwindow;
     subWindow.Close();
     SubWindow.hcount = count;
     SubWindow subWindow2 = new SubWindow();
     subWindow2.Show();
 }



//动态生成Items
 for(int i = 1; i <= SubWindow.count; i++)
 {
     combobox.Items.Add(i.ToString());
 }

11.在子窗口控制主窗口动态生成控件时,会出现两个相同的窗口 

解决办法:

在主窗口里

 public static SubWindow pwindow = null;

     public SubWindow()
     {
         InitializeComponent();
         pwindow = this;   //将当前窗口给pwindow,方便在setting里使用
     }

在子窗口里,

 SubWindow subWindow = SubWindow.pwindow;
 subWindow.Close();  //关闭上一个窗口

 SubWindow.hcount = count;
 SubWindow subWindow2 = new SubWindow();
 subWindow2.Show();

12.RadioButton

  <RadioButton GroupName="zu" Margin="20,10,0,10" Grid.Row="0"  Content="12" Click="RadioButton_Click"> </RadioButton>
  <RadioButton IsChecked="True" GroupName="zu" Margin="20,10,0,10" Grid.Row="1" Content="34" Click="RadioButton_Click"></RadioButton>


private void RadioButton_Click(object sender, RoutedEventArgs e)
{
    //获取radiobutton的值
    RadioButton radioButton = sender as RadioButton;
    radiobuttoncContent = radioButton.Content.ToString();
    if (radioButton.IsChecked == true)
    {
        SubWindow subWindow = SubWindow.pwindow;
        subWindow.Close();
        SubWindow subWindow2 = new SubWindow();
        subWindow2.Show();

    }
}

13.slider

<WrapPanel Margin="20,70,0,0">
    <TextBlock FontSize="14" LineHeight="12" Foreground="#333333">调整</TextBlock>
    <Slider x:Name = "slider2" Width="90" Minimum = "0" Maximum = "3"  ValueChanged = "slider1_ValueChanged" Margin = "23,0,0,0"></Slider>
    <TextBox x:Name="textbox1" Text="{Binding Textbox1}" Width="25" Height="25" Margin="5,-3,0,0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></TextBox>
</WrapPanel>


 public static int buttonSize = 0;

private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    string val = Convert.ToInt32(e.NewValue).ToString();
    //string msg = String.Format("Current value: {0}", val);
    this.textbox1.Text = val;
    buttonSize =Convert.ToInt32(val);
    SubWindow subWindow = SubWindow.pwindow;
    subWindow.Close();
    SubWindow subWindow2 = new SubWindow();
    subWindow2.Show();
}

14.动态生成控件

 private void CreateCanvas3()
 {
     LinearGradientBrush brush3 = (LinearGradientBrush)this.FindResource("Brush3");
     LinearGradientBrush brush2 = (LinearGradientBrush)this.FindResource("Brush2");
     Canvas canvas = new Canvas()
     {
         Margin = new Thickness(30 + buttonsize * 3 + Llength, 40 + buttonsize * 4 + hlength * 2, 90 + buttonsize * 3 + Llength, 40 + buttonsize * 3 + hlength * 2)
     };
     //成绩
     Border border = new Border()
     {
         BorderThickness = new Thickness(2),
         BorderBrush = System.Windows.Media.Brushes.WhiteSmoke,
         Background = brush3,
         CornerRadius = new CornerRadius(4),
         Margin = new Thickness(30 + buttonsize * 6, 20 + buttonsize * 6, 2 + buttonsize * 6, 0+buttonsize * 6),
         Height = 35 + buttonsize * 4,
         Width = 80 + buttonsize * 5
     };
    
     Label label = new Label()
     {
         Content = "123",
         FontSize = 14 + buttonsize * 2,
         Margin = new Thickness(15, 1, 15, 0),
         HorizontalContentAlignment = HorizontalAlignment.Center,
         VerticalContentAlignment = VerticalAlignment.Center,
     };
     //名称
     Border border2 = new Border()
     {
         BorderThickness = new Thickness(2,0,2,2),
         BorderBrush = System.Windows.Media.Brushes.WhiteSmoke,
         Background = brush3,
         CornerRadius = new CornerRadius(0,0,4,4),
         Margin = new Thickness(30 + buttonsize * 6, 53 + buttonsize * 6, 0 + buttonsize * 6, 0 + buttonsize * 6),
         Height = 35 + buttonsize * 4,
         Width = 80 + buttonsize * 5
     };
     Label label2 = new Label()
     {
         Content = "456",
         FontSize = 14 + buttonsize * 2,
         Margin = new Thickness(18, 1, 15, 0),
         HorizontalContentAlignment = HorizontalAlignment.Center,
         VerticalContentAlignment = VerticalAlignment.Center,
     };
     border.Child = label;
     border2.Child = label2;
     //组号
     Border border1 = new Border()
     {
         BorderThickness = new Thickness(2),
         BorderBrush = System.Windows.Media.Brushes.WhiteSmoke,
         Background = brush2,
         CornerRadius = new CornerRadius(50),
         Margin = new Thickness(15 + buttonsize * 4, 17 + buttonsize * 4, 0, 0),
         Height = 42 + buttonsize * 2,
         Width = 40 + buttonsize * 2
     };
     Label label1 = new Label()
     {
         Content = "1",
         FontSize = 14 + buttonsize * 2,
         HorizontalContentAlignment = HorizontalAlignment.Center,
         VerticalContentAlignment = VerticalAlignment.Center,
         Margin = new Thickness(0, 4, 0, 0),
         MinWidth = 40
     };
     border1.Child = label1;
     canvas.Children.Add(border);
     canvas.Children.Add(border2);
     canvas.Children.Add(border1);
     canvaswidth = 110;
     buttonwrap.Children.Add(canvas);
 }

 15.控件右击事件

右击事件是MouseRightButtonUp 

//windows.resource里定义一个ContextMenu
<ContextMenu x:Key="ContextMenu">
    <MenuItem Name="setting" Header="设置" Click="MenuItem_Click">
    </MenuItem>
</ContextMenu>


//右击事件是MouseRightButtonUp,右击之后出现ContextMenu里的设置
 <Grid MouseRightButtonUp="Mouse_RightButtonUp" Margin="0,10,0,0">
     <WrapPanel x:Name="buttonwrap">
     </WrapPanel>
 </Grid>


private void Mouse_RightButtonUp(object sender, MouseButtonEventArgs e)
{
    Grid sp = (Grid)sender;
    ContextMenu cm = new ContextMenu();
   ContextMenu ct= this.FindResource("ContextMenu") as ContextMenu;
   sp.ContextMenu = ct;
}


  //打开设置窗口
  private void MenuItem_Click(object sender, RoutedEventArgs e)
  {
      setting st = new setting();
      st.ShowDialog();
  }

16.窗体靠近屏幕左边隐藏,并生成一个小球

参考:

C# GetWindowRect用法-CSDN博客

c# 获取当前活动窗口句柄,获取窗口大小及位置 - jack_Meng - 博客园 (cnblogs.com)

WPF实现边缘依靠效果 - IPS99技术分享

C# 完美实现窗口边缘吸附功能 - 流泪的冰淇淋 - 博客园 (cnblogs.com)

wpf 如何让当前窗口隐藏_wpf 窗口关闭设置看不到-CSDN博客

wpf 类似于360加速球,的拖动和点击功能的实现_-CSDN问答

[小结][N种方法]实现WPF不规则窗体 - DebugLZQ - 博客园 (cnblogs.com)

WPF中控制窗口显示位置的三种方式 - LJD泊水 - 博客园 (cnblogs.com)

WPF中三种方法得到当前屏幕的宽和高_fullprimaryscreenheight-CSDN博客

在要隐藏的页面的xaml里:


    <Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown">
        <Image Stretch="Fill" Source="/WPFSharpWindow;component/cow.png" />
    </Grid>

cs:
  //定义2个变量记录信息
  Point _pressedPosition;
  bool _isDragMoved = false;

    
  [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  public static extern IntPtr GetForegroundWindow();

  [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

  [DllImport("user32.dll")]
  [return: MarshalAs(UnmanagedType.Bool)]
  static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

  [StructLayout(LayoutKind.Sequential)]
  public struct RECT
  {
      public int Left;                             //最左坐标
      public int Top;                             //最上坐标
      public int Right;                           //最右坐标
      public int Bottom;                        //最下坐标
  }

 

  public static MainWindow pwindow=null;
public MainWindow()
{
    InitializeComponent();
    pwindow = this;
}

+ private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 {
     this.DragMove();
      //获取当前屏幕的大小
      //  double screenheight = SystemParameters.PrimaryScreenHeight;
     //this.Left = e.GetPosition(this).Y - 50;
     _pressedPosition = e.GetPosition(this);
     IntPtr myptr = GetForegroundWindow();
     IntPtr awin = GetForegroundWindow();    //获取当前窗口句柄
     RECT rect = new RECT();
     GetWindowRect(awin, ref rect);
     double x = rect.Left;
     MessageBox.Show(x.ToString());
     if (x <= 1)
     {
         this.ShowInTaskbar = false;
         this.Visibility = Visibility.Hidden;
         Hide window1 = new Hide();
         //自定义控件显示位置
         window1.WindowStartupLocation = WindowStartupLocation.Manual;
         window1.Left = -50;
         window1.Top = 5;
         window1.Show();
     }
 }


//显示小球的界面:
<Window x:Class="Test.Window1"
        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:Test"
        mc:Ignorable="d"
        Title="Window1" Height="85" Width="85" Background="Transparent" AllowsTransparency="True" WindowStyle="None">
    <Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown" >
        <Border Background="blue" CornerRadius="190">
            <Button Click="Button_Click"  Background="Transparent" Width="50" Height="46" Margin="18,0,0,0">
                <Button.Resources>
                    <Style TargetType="{x:Type Border}">
                        <Setter Property="CornerRadius" Value="190"></Setter>
                        <Setter Property="BorderThickness" Value="0"></Setter>
                    </Style>
                </Button.Resources>
                <Image Source="/img/展开.png"></Image>
            </Button>
        </Border>
    </Grid>
</Window>

cs里:
   private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
   {
       this.DragMove();
       this.Left = e.GetPosition(this).Y-50;
   }

   private void Button_Click(object sender, RoutedEventArgs e)
   {
       MainWindow mainWindow = MainWindow.pwindow;
       //mainWindow.Show();
       mainWindow.ShowInTaskbar = true;
       mainWindow.Visibility = Visibility.Visible;
       //this.Visibility = Visibility.Hidden;
       this.ShowInTaskbar = false;
       this.Visibility=Visibility.Hidden;
   }

17.wpf 记忆上次关闭时窗口的位置,并在下次打开时读取位置

参考:

WPF编程,窗口保持上次关闭时的大小与位置。_closing="window_closing-CSDN博客

 若是没有settings文件,可以右击项目-添加-配置文件

1.在settings添加变量

2.在窗口关闭事件中保存窗口位置

private void Button_Click(object sender, RoutedEventArgs e)
{
    Settings.Default.Left =this.RestoreBounds.Left;
    Settings.Default.Top = this.RestoreBounds.Top;
    Settings.Default.Save();
    this.Close();
}

3.在窗口的构造函数中读取位置

 //读取配置文件
 try
 {
     //设置位置、大小
     //Rect restoreBounds = Properties.Settings.Default.MainRestoreBounds;
     //this.WindowState = WindowState.Normal;
     this.Left = Settings.Default.Left;
     this.Top = Settings.Default.Top;
 }
 catch { }   

18.鼠标悬停事件

参考:WPF鼠标事件简介_wpf 鼠标悬浮事件-CSDN博客

19.窗口圆角

//在window里写入WindowStyle="None" AllowsTransparency="True" Background="Transparent" OpacityMask="White"

<Window x:Class="Test.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"
        PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown"
        PreviewMouseMove="Window_PreviewMouseMove"
        PreviewMouseLeftButtonUp="Window_PreviewMouseLeftButtonUp"
        xmlns:local="clr-namespace:Test"
         ResizeMode = "NoResize"
        mc:Ignorable="d"
        Title="" Height="720" Width="200" WindowStyle="None" AllowsTransparency="True" Background="Transparent" OpacityMask="White">

    <Border Width="200" CornerRadius="15"  BorderThickness="2" Margin="2,0,2,0" Background="Firebrick">
        <Grid>
            <Border CornerRadius="30,30,30,30">
                <TextBlock>123</TextBlock>
            </Border>
        </Grid>
    </Border>              
</Window>

20.wpf设置gif动图为背景

1.WpfAnimatedGIF

参考:

在WPF显示动态GIF图片 - 雨也绵绵 - 博客园 (cnblogs.com)

1.添加nuget包,安装WpfAnimatedGIF,

2.添加  xmlns:gif="http://wpfanimatedgif.codeplex.com"

3.引用:

<Window x:Class="Test.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:gif="http://wpfanimatedgif.codeplex.com"
        xmlns:local="clr-namespace:Test"
        //在设计模式下可以看见效果
        gif:ImageBehavior.AnimateInDesignMode="True"
        mc:Ignorable="d"
        Title="MainWindow" Height="750" Width="1200">

调用:
<Grid.Background>
    <VisualBrush>
        <VisualBrush.Visual>
            <Image gif:ImageBehavior.AnimatedSource="\img\R-C.gif"></Image>
        </VisualBrush.Visual>
    </VisualBrush>
</Grid.Background>

2. ImageAnimator

参考:

WPF加载GIF的五种方式(Storyboard / WpfAnimatedGif / ImageAnimator / PictureBox / MediaElement) - WebEnh - 博客园 (cnblogs.com)

cs:
调用:
imgGifShow.ImageSource = GetGifImage(path);


更换动图或关闭时:要把ImageSource设为空,以防内存泄漏
if (imgPath.EndsWith(".gif"))
{
    StopAnimate();
}
imgGifShow.ImageSource = null;




 #region 显示动图
 public BitmapSource GetGifImage(string path)
 {
     this.gifBitmap = new Bitmap(path);
     imgPath = path;
     this.bitmapSource = this.GetBitmapSource();
     //this.imgGifShow.ImageSource = this.bitmapSource;
     StartAnimate();
     return bitmapSource;
 }

 /// <summary>
 /// 从System.Drawing.Bitmap中获得用于显示的那一帧图像的BitmapSource
 /// </summary>
 /// <returns></returns>
 private BitmapSource GetBitmapSource()
 {
     IntPtr handle = IntPtr.Zero;
     try
     {
         handle = this.gifBitmap.GetHbitmap();
         this.bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
     }
     finally
     {
         if (handle != IntPtr.Zero)
         {
             DeleteObject(handle);
         }
     }
     return this.bitmapSource;
 }

 /// <summary>
 /// Start
 /// </summary>
 public void StartAnimate()
 {
     ImageAnimator.Animate(this.gifBitmap, this.OnFrameChanged);
 }

 /// <summary>
 /// Stop
 /// </summary>
 public void StopAnimate()
 {
     ImageAnimator.StopAnimate(this.gifBitmap, this.OnFrameChanged);
 }

 /// <summary>
 /// 帧处理
 /// </summary>
 private void OnFrameChanged(object sender, EventArgs e)
 {
     Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
     {
         ImageAnimator.UpdateFrames(); // 更新到下一帧
         if (this.bitmapSource != null)
         {
             this.bitmapSource.Freeze();
         }

         this.bitmapSource = this.GetBitmapSource();
         this.imgGifShow.ImageSource = this.bitmapSource;
         this.InvalidateVisual();
     }));
 }

 private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
 {
     StopAnimate();
 }

 /// <summary>
 /// 删除本地 bitmap resource
 /// </summary>
 [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 [return: MarshalAs(UnmanagedType.Bool)]
 static extern bool DeleteObject(IntPtr hObject);
 #endregion

21.倒计时功能

倒计时有三种写法:

1. DispatcherTimer:

DispatcherTimer是为 WPF 专门设计的,不然的话会提示界面资源被其他线程所拥有而无法更新界面。DispatcherTimer 是在 UI 线程跑的可以直接更新 UI 

DispatcherTimer 定时器不是单独开启一个线程来运行定时器方法,而是和主线程是同一个线程,只是通过改变运行优先级来实现定时器,当定时器时间到了,主线程就转去执行定时器方法。因此DispatcherTimer定时器不要用来实现执行时间长的任务,不然会使主线程很卡,导致WPF界面很难看,用户不友好!

参考:WPF实现倒计时_wpf 倒计时-CSDN博客

xaml:
 <Border x:Name="DJSBorder" Width="130" Height="130" HorizontalAlignment="Right" Margin="0,0,100,0" Visibility="Collapsed">
     <Border.Background>
         <ImageBrush ImageSource="\img\倒计时@2x.png"></ImageBrush>
     </Border.Background>
     <TextBox x:Name="DaoJiShi" IsEnabled="False" Width="70" Height="70"  FontSize="70" Background="Transparent" BorderThickness="0" 
              VerticalContentAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,20"></TextBox>
 </Border>

//签到按钮
  <Button x:Name="qiandao" Width="80" Height="40" Style="{StaticResource btn1}" FontSize="18" HorizontalAlignment="Left" VerticalAlignment="Top" 
          Margin="30" Click="QianDao_Click">签到</Button>



cs:

private int Second = 10;

 //倒计时
 public void disTimer_Tick(object sender, EventArgs e)
 {
     Second--;
     if (Second <0)
     {
         MessageBox.Show("倒计时已结束!", "系统提示", MessageBoxButton.OK, MessageBoxImage.Warning);
         this.disTimer.Stop();//计时停止
         //DJSBorder.Visibility = Visibility.Collapsed;
     }
     else
     {
       
         if (Second <= 3)
         {
             DaoJiShi.Foreground = System.Windows.Media.Brushes.Red;
         }
         else
         {
             DaoJiShi.Foreground = System.Windows.Media.Brushes.Yellow;
         }
         //判断是否处于UI线程上
         //判断是否处于UI线程上
         if (DaoJiShi.Dispatcher.CheckAccess())
         {
             DaoJiShi.Text = Second.ToString();
         }
         else
         {
             DaoJiShi.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
             {
                 DaoJiShi.Text = Second.ToString();
             }));
         } 
     }
 }
 private DispatcherTimer disTimer = new DispatcherTimer();
 public void CountDown()
 {

     disTimer.Tick += new EventHandler(disTimer_Tick);//每一秒执行的方法
     disTimer.Interval = new TimeSpan(10000000); //时间间隔为一秒。
                                                 //因为设置时间间隔后,计时开始后会先过一秒才开始显示倒数计时的时间,这么算起来相当于是多计时了一秒,
                                                 //所以要在计时开始前先设置textbox里的值
                                                 //然后在计时开始后就减一操作
     DaoJiShi.Text = Second.ToString();
     DaoJiShi.Foreground = System.Windows.Media.Brushes.Yellow;
     disTimer.Start();//计时开始
 }

2.System.Timers.Timer  

组件Timer是基于服务器的计时器,在属性中的毫秒Interval数过后,该计时器在应用程序中引发Elapsed事件。 可以将 对象配置为 Timer 仅引发一次事件,也可以使用 属性重复引发事件 AutoReset 。 通常, Timer 对象在类级别声明,以便只要需要,它就保留在范围内。 然后,可以处理其 Elapsed 事件以提供常规处理。 例如,假设关键服务器必须保持每周 7 天、每天 24 小时运行。 可以创建一个Timer服务,该服务使用 对象定期检查服务器并确保系统正常运行。 如果系统未响应,服务可能会尝试重启服务器或通知管理员。

Timer 是在非UI线程跑的,不能直接操作UI控件

System.Timers.Timer如果在 WPF 应用程序中使用 ,请注意,在System.Timers.Timer用户界面 (UI) 线程的线程上运行。 若要访问用户界面 (UI) 线程上的对象,需要使用Dispatcher.Invoke 或 BeginInvoke将操作
发布到用户界面 (UI) 线程
上。

  System.Timers.Timer timer = null;

 public StartBiaoJue(string value1)
 {
     InitializeComponent();

     timer = new System.Timers.Timer(1000);  //计时间隔为1秒
     timer.Elapsed += Timer_Elapsed;
     timer.AutoReset = true;
     timer.Enabled = true;   //开启计时
}

private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Second--;

    //创建一个委托,用于封装一个方法,在这里是封装了 控制更新控件 的方法
    Dispatcher.Invoke(() =>
    {
        // 更新UI元素
        DaoJiShi.Text = Second.ToString();   //文本框值更改
        if (Second <= 3 && Second >0)
        {
            DaoJiShi.Foreground = System.Windows.Media.Brushes.Red;
        }
        if (Second == 0)
        {
            timer.Enabled = false;       //关闭计时
            DJSBorder.Visibility = Visibility.Collapsed;
          
        }
    });
}

private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Second--;

    //创建一个委托,用于封装一个方法,在这里是封装了 控制更新控件 的方法
    Dispatcher.BeginInvoke(new Action(() =>
    {
        // 更新UI元素
        DaoJiShi.Text = Second.ToString();   //文本框值更改
        if (Second <= 3 && Second >0)
        {
            DaoJiShi.Foreground = System.Windows.Media.Brushes.Red;
        }
        if (Second == 0)
        {
            timer.Enabled = false;       //关闭计时
            DJSBorder.Visibility = Visibility.Collapsed;
          
        }
    });
}

3.System.Threading.Timer

System.Threading.Timer 是由线程池调用的。
所有的Timer对象只使用了一个线程来管理。这个线程知道下一个Timer对象在什么时候到期。下一个Timer对象到期时,线程就会唤醒,在内部调用ThreadPool 的 QueueUserWorkItem,将一个工作项添加到线程池队列中,使你的回调方法得到调用。如果回调方法的执行时间很长,计时器可能(在上个回调还没有完成的时候)再次触发。这可能造成多个线程池线程同时执行你的回调方法。

 没实际用,因此没代码

可参考:Timer 类 (System.Threading) | Microsoft Learn

22.两个窗口间传值(委托)

1.主窗口向子窗口传值

1.可以在子窗口里定义一个变量用来接收值
子窗口cs里:

     public string test_str { get; set; }

        public child_window()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            tb_receive.Text = test_str;
        }
主窗口cs里:
    private void Button_Click(object sender, RoutedEventArgs e)
        {
            child_window child_Window = new child_window();
            child_Window.test_str = tb_message.Text;
            child_Window.Show();
        }

2.直接通过构造函数来实现 重载
子窗口构造函数改为:也可以再添加一个构造函数,多个构造函数只要参数不同,就不冲突。
    public child_window(string str)
        {
            InitializeComponent();
             tb_receive.Text=str;
        }
主窗口里:
    private void Button_Click(object sender, RoutedEventArgs e)
        {
            //把值当参数传到子窗口里
            child_window child_Window = new child_window(tb_message.Text);
            child_Window.Show();
        }

2.子窗口向主窗口传值(利用委托)

子窗口:
    public delegate void SendMessage(string value);
        public SendMessage sendMessage;
        public child_window()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            sendMessage(tb_send.Text);
        }


主窗口:
    public void Recevie(string value)
        {
            tb_recevie.Text = value;
        }

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            child_window child_Window = new child_window();
            child_Window.sendMessage = Recevie;
            child_Window.Show();
        }

  • 21
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值