当前位置:   article > 正文

C#学习(八)——WPF基础入门_c#wpf

c#wpf

一、XAML页面基础

使用控件
1.利用工具箱,通过点击拖拽使用工具箱内部的任何控件
2.在XMAL中代码控制,例如添加一个按钮 Button,以下三个代码实现效果相同
代码1

<Button Height="50" Width="100" Content="Click Me!"></Button>
  • 1

代码2

<Button>
    <Button.Height>50</Button.Height>
    <Button.Width>100</Button.Width>
    <Button.Content>Click Me!</Button.Content>
</Button>
  • 1
  • 2
  • 3
  • 4
  • 5

代码3

<Button>
    <Button.Height>50</Button.Height>
    <Button.Width>100</Button.Width>
    <Button.Content>
        <TextBlock>Click Me!</TextBlock>
    </Button.Content>
</Button>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

XMAL的根元素Window

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.xmlns:xml-namespace,定义命名空间,xmlns为默认命名空间
2.带有“:”的命名空间:xmlns:x, xmlns:d, xmlns:mc, xmlns:local 都与解析XMAL语言相关
3.Title=“MainWindow” Height=“450” Width=“800”,定义了标题、高度和宽度
4. mc:Ignorable,表示运行过程中可以忽略的空间,如<d:Button> 表示运行时,该按钮即被忽略
对应的C#实现代码
MainWindow.xaml.cs

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();//初始化页面
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

利用C#代码进行页面控件的操作
依旧是添加一个按钮为例

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var grid = (Grid)this.Content;
            Button button = new Button();
            button.Height = 50;
            button.Width = 100;
            Margin = new Thickness(0, 0, 700, 385);
            button.Content = "This is a Button!";

            grid.Children.Add(button);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

但是仍然建议使用XAML对页面布局进行控制!!!

*二、(拓展)MVC架构

什么是MVC?

  • [ 软件工程的架构方式 ]

  • [ 模型(Model)、视图(View)、控制器(Controller) ]

  • [ 分离业务操作、数据显示、逻辑控制 ]
    视图 View

  • [ 用户交互界面 ]

  • [ 仅展示数据,不处理数据 ]

  • [ 接受用户输入 ]
    模型 Model

  • [ MVC架构核心 ]

  • [ 表示业务模型或数据模型 ]

  • [ 业务逻辑,如算法实现、数据的管理、输出对象的封装等 ]
    控制器 Controller

  • [ 接收用户的输入,并调用模型和视图去完成用户的请求处理 ]

  • [ 不处理数据 ]

  • [ 返回视图,显示数据 ]

MVC数据流动示意图MVC数据流动
MVC的优点

  • [ 耦合性低,视图层业务层分离 ]
  • [ 可复用性高,多个视图可以访问一个模型 ]
  • [ 可维护性高 ]

三、逻辑树与视觉树

MainWindow.xaml

<StackPanel>
    <TextBlock HorizontalAlignment="Center" Margin="20">Hello World!</TextBlock>
    <ListBox Height="100" Width="100">
        <ListBoxItem Content="item1"></ListBoxItem>
        <ListBoxItem Content="item2"></ListBoxItem>
        <ListBoxItem Content="item3"></ListBoxItem>
        <ListBoxItem Content="item4"></ListBoxItem>
    </ListBox>
    <Button Margin="20" Width="100" Click="Button_Click">就是个按钮</Button>
</StackPanel>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("按钮已经被点击");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

当点击弹窗按钮时,此时执行Button_Click的方法,弹出消息框,此时的按钮点击事件运行在逻辑树上。
视觉树
在此图中,可以看到视觉树的节点,从树根MainWindow出发,同样也有一些逻辑节点如StackPanel。因此,从逻辑上来说,逻辑树是视觉树的子集。

四、Grid网格系统

<Grid>
    <Grid.ColumnDefinitions><!--列的定义-->
        <ColumnDefinition Width="auto"></ColumnDefinition>
        <ColumnDefinition Width="auto"></ColumnDefinition>
    </Grid.ColumnDefinitions>
</Grid>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当width = “auto”时,列的宽度将自动等于文字的长度

<ColumnDefinition Width="*"></ColumnDefinition>
 <ColumnDefinition Width="2*"></ColumnDefinition>
  • 1
  • 2

当width = “”时,列的宽度为权重,即第二列权重为第一列的两倍
示例代码:创建一个3
3的网格

<Grid>
    <Grid.ColumnDefinitions><!--列的定义-->
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Grid.Column="0">Click me 1</Button>
    <Button Grid.Row="0" Grid.Column="1">Click me 2</Button>
    <Button Grid.Row="1" Grid.Column="0">Click me 3</Button>
    <Button Grid.Row="1" Grid.Column="1">Click me 4</Button>
    <TextBlock Grid.Row="2" Grid.Column="0">Hello world</TextBlock>
</Grid>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

五、依赖属性与数据处理

创建一个按钮,鼠标悬停时,按钮变色,字体变大,变色;此过程就是通过属性依赖来完成的。

<Grid>
    <Button Height="100" Width="200" Content="Click Me">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="FontSize" Value="25"></Setter>
                        <Setter Property="Foreground" Value="White"></Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
</Grid>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

六、数据绑定 Date Binding

四种数据绑定方式
1.单向绑定 one way binding : Source -> Target
2.双向绑定 two way binding : Source <-> Target
3.指定方向单向绑定 oneWayToSource Target -> Source
4.单次绑定 One Time -> 构造方法中单次执行

以拖动滑块与现实数据为例,体验四种方式的不同效果
注: 双向绑定中,在不使用UpdateSourceTrigger=PropertyChanged 时,需要按下tab键,滑块发生变化。UpdateSourceTrigger=PropertyChanged 效果为使得键入数字滑块自动变化。

<StackPanel>
    <!--单向绑定-->
    <TextBox Width="100" Margin="50" Text="{Binding ElementName=mySlider, Path=Value, Mode=OneWay}"></TextBox>
    <Slider x:Name="mySlider" Minimum="0" Maximum="100" IsSnapToTickEnabled="True" ValueChanged="mySlider_ValueChanged"/>
    <!--IsSnapToTickEnabled使显示数字为整数-->
    <!--双向绑定-->
    <TextBox Width="100" Margin="50" Text="{Binding ElementName=mySlider2, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
    <Slider x:Name="mySlider2" Minimum="0" Maximum="100" IsSnapToTickEnabled="True" ValueChanged="mySlider_ValueChanged"/>
    <!--指定方向单向绑定-->
    <TextBox Width="100" Margin="50" Text="{Binding ElementName=mySlider3, Path=Value, Mode=OneWayToSource}"></TextBox>
    <Slider x:Name="mySlider3" Minimum="0" Maximum="100" IsSnapToTickEnabled="True" ValueChanged="mySlider_ValueChanged"/>
    <!--单次绑定-->
    <TextBox Name="myTextBox" Width="100" Margin="50" Text="{Binding ElementName=mySlider4, Path=Value, Mode=OneTime}"></TextBox>
    <Slider x:Name="mySlider4" Minimum="0" Maximum="100" IsSnapToTickEnabled="True" ValueChanged="mySlider_ValueChanged"/>

</StackPanel>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

MainWindow.xaml.cs

public MainWindow()
{
    InitializeComponent();
    mySlider4.Value = 35;
    myTextBox.Text = mySlider4.Value.ToString();//从slider到TextBox的一次性绑定
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

七、INotifyPropertyChanged 事件处理

INotifyPropertyChanged 这个接口可以帮助我们追踪UI控件中的属性变化情况

示例代码:实现一个加法器

<StackPanel>
    <Label Content="number1"></Label>
    <TextBox Width="200" Margin="30" Text="{Binding Path=Num1, Mode= TwoWay}"></TextBox>
    <Label Content="number2"></Label>
    <TextBox Width="200" Margin="30" Text="{Binding Path=Num2, Mode= TwoWay}"></TextBox>
    <Label Content="result"></Label>
    <TextBox Width="200" Margin="30" Text="{Binding Path=Result, Mode= TwoWay}"></TextBox>
</StackPanel>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public Sum Sum { get; set; }
    public MainWindow()
    {
        InitializeComponent();

        Sum = new Sum() { Num1 = "1", Num2 = "2" };
        this.DataContext = Sum;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Sum.cs

public class Sum : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    private void OnPropertyChanged(string property)
    {
        if(PropertyChanged == null)
        {
            return;
        }
        PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    private string _num1;
    private string _num2;
    private string _result;

    public string Num1
    {
        get
        {
            return _num1;
        }
        set
        {
            int number;
            bool result = int.TryParse(value, out number);//处理string到整数的转化过程
            if(result)
            {
                _num1 = value;
                OnPropertyChanged("Num1");//发送事件
                OnPropertyChanged("Result");
            }
        }
    }
    public string Num2
    {
        get
        {
            return _num2;
        }
        set
        {
            int number;
            bool result = int.TryParse(value, out number);//处理string到整数的转化过程
            if (result)
            {
                _num2 = value;
                OnPropertyChanged("Num2");//发送事件
                OnPropertyChanged("Result");
            }
        }
    }
    public string Result
    {
        get
        {
            int result = int.Parse(_num1) +int.Parse(_num2);
            return result.ToString();
        }
        set
        {
            int result = int.Parse(_num1) + int.Parse(_num2);
            _result = result.ToString();
            OnPropertyChanged("Result");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/169866
推荐阅读
相关标签
  

闽ICP备14008679号