十年河東,十年河西,莫欺少年窮
學無止境,精益求精
最近在知乎,看了很多提問,涉及到就業,裁員,經濟等,不看不知道,越看越頭疼,知乎上很多人提問
畢業生就業如何難,2023年裁員如何嚴重,35歲的中年危機,程序員被裁員後找不到工作該,經濟如何差等話題
哎,這讓我這個35歲的老程序員感到莫大的壓力,我時常想,如果我離開了現在的公司,我能找到工作嗎?多久能找到工作?如果找不到工作,我能幹什麼?
35歲,本是經驗技術相對比較成熟的階段,更是上有老下有小的年齡段,也是花錢多的時候,如果在這個年齡段沒了收入,該多麼絕望......,但沒辦法,世界就是如此,它不會顧及你的感受,生存法則而已
言歸正傳,在開始正文之前,小夥伴們看下知乎上提的一個話題:35歲了,還有必要繼續卷技術嗎? 你們認爲呢?
本來鄙人也不打算繼續內捲了,但中年危機的壓迫感,迫使我不得不拿起手中的槍,繼續戰鬥!我本是做web開發的,但C#語言似乎CS開發崗位更多,而且似乎不受年齡限制,大不了40歲進廠做工控機開發唄,再說了,廠裏妹子不是多麼,挺好的
1、事件驅動模式
這種方式類似於winform,不推薦使用
新建如下頁面
<Window x:Class="WpfApp.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:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl" xmlns:local="clr-namespace:WpfApp" mc:Ignorable="d" Title="MainWindow" Height="600" Width="1080"> <Window.Resources> <Style TargetType="Button" x:Key="baseStl"> <Setter Property="Width" Value="200"/> <Setter Property="Height" Value="80"/> <Setter Property="Background" Value="Yellow"/> <Setter Property="FontSize" Value="22"/> </Style> <Style TargetType="Button" x:Key="Butn" BasedOn="{StaticResource baseStl}"> <Setter Property="Content" Value="Btu"/> </Style> </Window.Resources> <Grid> <StackPanel> <Slider x:Name="slider" Maximum="100" Minimum="0" ValueChanged="Slider_ValueChanged" Margin="5" Foreground="red" ></Slider> <TextBox x:Name="textbox1" Margin="5" Height="30" TextChanged="TextBox_TextChanged"/> <TextBox x:Name="textbox2" Margin="5" Height="30" TextChanged="TextBox_TextChanged" /> <Button x:Name="button" Style="{StaticResource Butn}" Command="{Binding BtnCommand}" Width="100" Height="100" Content="點我" /> </StackPanel> </Grid> </Window>
注意:Slider_ValueChanged 事件 及 TextBox_TextChanged 事件
代碼如下:
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { textbox1.Text = slider.Value.ToString(); textbox2.Text = slider.Value.ToString(); } private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { if (double.TryParse(textbox1.Text, out double result)) { slider.Value = result; } }
這種模式最大的缺點是前後端混合在一起,不方便維護。下面介紹第二種方式,控件驅動控件。
2、控件驅動控件
新建如下頁面
此時後臺事件代碼去掉,前端驅動事件去掉,xaml如下:
<Window x:Class="WpfApp.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:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl" xmlns:local="clr-namespace:WpfApp" mc:Ignorable="d" Title="MainWindow" Height="600" Width="1080"> <Window.Resources> <Style TargetType="Button" x:Key="baseStl"> <Setter Property="Width" Value="200"/> <Setter Property="Height" Value="80"/> <Setter Property="Background" Value="Yellow"/> <Setter Property="FontSize" Value="22"/> </Style> <Style TargetType="Button" x:Key="Butn" BasedOn="{StaticResource baseStl}"> <Setter Property="Content" Value="Btu"/> </Style> </Window.Resources> <Grid> <StackPanel> <Slider x:Name="slider" Maximum="100" Minimum="0" Margin="5" Value="{Binding ElementName=textbox1,Path=Text,Mode=TwoWay}" ></Slider> <TextBox x:Name="textbox1" Margin="5" Height="30" Text="{Binding ElementName=slider,Path=Value,Mode=TwoWay}" /> <Button x:Name="button" Style="{StaticResource Butn}" Command="{Binding BtnCommand}" Width="100" Height="100" Content="點我" /> </StackPanel> </Grid> </Window>
重點解讀
<Slider x:Name="slider" Maximum="100" Minimum="0" Margin="5" Value="{Binding ElementName=textbox1,Path=Text,Mode=TwoWay}" ></Slider>
及
<TextBox x:Name="textbox1" Margin="5" Height="30" Text="{Binding ElementName=slider,Path=Value,Mode=TwoWay}" />
Slider 的 value 的取值爲綁定模式,綁定的是元素Element的Name爲 textbox1,取的是textbox1的text值,Mode模式爲雙向綁定綁定,(WPF默認模式爲單向綁定模式)
TextBox 的 Text 的取值爲綁定模式,綁定的是元素Element的Name爲 slider,取的是slider的value值,Mode模式爲雙向綁定綁定,(WPF默認模式爲單向綁定模式)
3、數據驅動模式(數據上下文模式)
需求要求:進度條初始值爲20,點擊按鈕後,進度條的值變爲88,且彈框提示
3.1、按鈕點擊需要用到Wpf的Command命令
新建BaseCommand類,並實現接口 ICommand
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace WpfApp.Models { public class BaseCommand : ICommand { public Action action; public BaseCommand(Action action) { this.action = action; } public event EventHandler CanExecuteChanged; public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { action(); } } }
3.2、先建viewModel如下:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.ComponentModel; using System.Windows.Input; using System.Messaging; using System.Windows; namespace WpfApp.Models { public class MainWindowModel : INotifyPropertyChanged { public ICommand BtnCommand { get; set; } public MainWindowModel() { //進度條模式爲20 this.wendu = 20; BtnCommand = new BaseCommand(DoBtnCommand); } public void DoBtnCommand() { this.wendu = 88; MessageBox.Show("進度條的值修改爲88,進度條向前歡動了。"); } private ushort _wendu; public ushort wendu { get { return this._wendu; } set { this._wendu = value; this.OnPropertyChanged("wendu"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } }
3.3、修改xaml的數據上下文
public MainWindow() { InitializeComponent(); this.DataContext = new MainWindowModel(); }
3.4、xaml如下
<Window x:Class="WpfApp.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:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl" xmlns:local="clr-namespace:WpfApp" mc:Ignorable="d" Title="MainWindow" Height="600" Width="1080"> <Window.Resources> <Style TargetType="Button" x:Key="baseStl"> <Setter Property="Width" Value="200"/> <Setter Property="Height" Value="80"/> <Setter Property="Background" Value="Yellow"/> <Setter Property="FontSize" Value="22"/> </Style> <Style TargetType="Button" x:Key="Butn" BasedOn="{StaticResource baseStl}"> <Setter Property="Content" Value="Btu"/> </Style> </Window.Resources> <Grid> <StackPanel> <Slider x:Name="slider" Maximum="100" Minimum="0" Margin="5" Value="{Binding wendu}" ></Slider> <TextBox x:Name="textbox1" Margin="5" Height="30" Text="{Binding wendu}" /> <Button x:Name="button" Style="{StaticResource Butn}" Command="{Binding BtnCommand}" Width="100" Height="100" Content="點我" /> </StackPanel> </Grid> </Window>
3.5、另一種實現模式(主要是Command實現類)
ICommand的實現類(通過屬性賦值Action委託,上面方法是通過構造函數賦值Action委託)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace WpfApp.Models { /// <summary> /// 屬性賦值action模式 /// </summary> public class CommandBase : ICommand { public event EventHandler CanExecuteChanged; /// <summary> /// 是否可執行 /// </summary> /// <param name="parameter"></param> /// <returns></returns> public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { action.Invoke(parameter); } public Action<object> action { get; set; } } }
viewModel如下
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace WpfApp.Models { public class MainWindowMod : INotifyPropertyChanged { //新建按鈕點擊事件 public ICommand BtnCommand { get; set; } public MainWindowMod() { this.wendu = 20; //執行委託 BtnCommand = new CommandBase() { action = new Action<object>(DoBtnCommand) }; } public void DoBtnCommand(object obj) { this.wendu = 88; MessageBox.Show("進度條的值修改爲88,進度條向前歡動了。"); } private ushort _wendu; public ushort wendu { get { return this._wendu; } set { this._wendu = value; this.OnPropertyChanged("wendu"); } } /// <summary> /// 用於雙向綁定 /// </summary> public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } }
優化如下:
如果每次都需要寫 "wendu" ,有可能會寫錯
this.OnPropertyChanged("wendu");
優化代碼如下
public class MainWindowMod : INotifyPropertyChanged { //新建按鈕點擊事件 public ICommand BtnCommand { get; set; } public MainWindowMod() { this.wendu = 20; //執行委託 BtnCommand = new CommandBase() { action = new Action<object>(DoBtnCommand) }; } public void DoBtnCommand(object obj) { this.wendu = 88; MessageBox.Show("進度條的值修改爲88,進度條向前歡動了。"); } private ushort _wendu; public ushort wendu { get { return this._wendu; } set { this._wendu = value; this.OnPropertyChanged(); } } /// <summary> /// 用於雙向綁定 /// </summary> public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName="") { if (PropertyChanged != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
@天才臥龍的波爾卡