cs 中
1. 添加 icon
选择图片并转换成ico格式:https://convertio.co/zh/download/8441dcb3979589069571b8c7295903474957c6/
然后右键属性中添加icon
2. Regex的replace方法替换,实现首字母大写
private void Add_Click(object sender, RoutedEventArgs e) { Button btn = (Button)sender; btn_content = (String)btn.Content; if (total.Equals("") || total.EndsWith('!') || total.EndsWith('.') || total.EndsWith('?')) { // capitalize the first letter firstContent = btn_content[1].ToString().ToUpper(); // original first letter that need to be replaced Regex regex = new Regex(btn_content[1].ToString()); // only replace once btn_content = regex.Replace(btn_content, firstContent, 1); } total += btn_content; Result.Content = total; }
3. 方法中带默认值
private decimal calcAmount(int quantity = 1, decimal price = 100m) { decimal amount = 0; if (quantity > 0 && price > 0) amount = quantity * price; return amount; }
4. 边验证边改变值,use "ref"
decimal friesAmt = 110; if (refCalcAmount(QuantityFries, FRIES_PRICE, ref friesAmt)) AmountFries = friesAmt; private bool refCalcAmount(int quantity, decimal price, ref decimal amount) { price *= 1.13m; bool isValid = quantity >= 0 && price > 0; if(isValid) amount = quantity * price; return isValid; }
or use "out"
private bool tryCalcAmount(int quantity, decimal price, out decimal amount) { bool isValid = quantity >= 0 && price > 0; amount = isValid ? quantity * price : 0m; return isValid; }
or use return
private (bool, decimal) tryCalcAmount(int quantity, decimal price) { bool isValid = quantity >= 0 && price > 0; decimal amount = isValid ? quantity * price : 0m; return (isValid, amount); }
5. padLeft / padRight:在左边 / 右边加space
Console.Write("Key".PadRight(15));
6. 属性
简化,不需要同步属性changed
public ObservableCollection<Game> Games { get; set; } = new ObservableCollection<Game>();
public int CurrentGuess { get; set; }
需要同步
//the convention is to use the same name but upper for public and lower case first letter for private private string cheerMessage = ""; public string CheerMessage { get => cheerMessage; set { cheerMessage = value; propertyChanged(); } }
构造器赋值:
public class Item { // 构造器1 public Item() { Prop1 = ""; Prop2 = -1; } // 构造器2 public Item(string p1, int p2) { Prop1 = p1; Prop2 = p2; } public string Prop1 { get; set; } public int Prop2 { get; set; } }
Item item1 = new Item(); Item item2 = new Item("second", 2); Item item3 = new Item(); item3.Prop1 = "third"; item3.Prop2 = 3; // 新方法 Items.Add(new Item { Prop1 = "fourth", Prop2 = 4 });
8. new class, 并初始化
public class Game { //change the names to be consistent with the rest of my naming public int Number { get; set; } public string Guesses { get; set; } public int Answer { get; set; } }
curGame = new Game { Number = gameCounter++, Answer = rand.Next(MIN_NUM, MAX_NUM + 1), Guesses = "" };
9. validation
0) 为null or whitespace
if (curGame == null || !string.IsNullOrWhiteSpace(curGame.Guesses))
1)限制输入,用keydown
enter键调用方法
KeyDown="TextBox_KeyDown"
private void TextBox_KeyDown(object sender, KeyEventArgs e) { // 数字0-9 可以输入,other:prohibited if ((e.Key >= Key.D0 && e.Key <= Key.D9) | (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9)) e.Handled = false; // enter键调用guess_click()方法 else if (e.Key == Key.Enter) Guess_Click(sender, e); // in this case, it has to be Guess_Click() rather than viewModel.GuessNumber(); else e.Handled = true; // prohibited }
2)使用 previewTextInput
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { // transfer to "int" -> success -> true -> when "false", the input is allowed; when "true", prohibited e.Handled = !int.TryParse(e.Text, out _); }
xaml: PreviewTextInput="TextBox_PreviewTextInput"
或者用 Regex e.Handled = new Regex("[^0-9/.]").IsMatch(e.Text);
(但应该是(@"^xxxxx$"), I reckon)
3)validator
第一步: ValidationTemplate + 错误styleTemplate
① Template改变边框,显示错误信息
在 <Window.Resources> 中或 App.xaml
显示框外红*
<ControlTemplate x:Key="ValidationTemplate"> <!-- streching it to fill the entire height or width.--> <DockPanel> <AdornedElementPlaceholder/> // tell the UIElement where to place the template <TextBlock Foreground="Red" FontSize="20">*</TextBlock> </DockPanel> </ControlTemplate>
显示ValidationResult并改变border颜色
<ControlTemplate x:Key="errorTemplate"> <Border BorderBrush="OrangeRed" BorderThickness="2" > <Grid> <AdornedElementPlaceholder/> <TextBlock Text="{Binding [0].ErrorContent}" Foreground="OrangeRed" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,12,0" /> </Grid> </Border> </ControlTemplate>
合并显示:DockPanel里面用【AdornedElementPlaceHolder】locate到Border,然后增加TextBlock
<ControlTemplate x:Key="errorTemplate"> <DockPanel> <Border BorderBrush="OrangeRed" BorderThickness="2" > <Grid> <AdornedElementPlaceholder/> <TextBlock Text="{Binding [0].ErrorContent}" Foreground="red" --> 其中的errorContent就是ValidationResult,表示只显示第一个result VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,12,0" /> </Grid> </Border> <TextBlock Foreground="Red" FontSize="20">*</TextBlock> </DockPanel> </ControlTemplate>
效果:
② 使用ToolTip 显示错误信息
<Style x:Key="TextBoxInError" TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="Background" Value="Transparent"/> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style>
使用: Style="{StaticResource TextBoxInError}"
效果:
第二步:ValidationRule
<TextBox Name="txtHeight" Margin="10" FontSize="18" Height ="30" Grid.ColumnSpan="2" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"
Validation.ErrorTemplate="{StaticResource ValidationTemplate}" 此处使用ValidationTemplate Style="{StaticResource TextBoxInError}"> <Binding Path="Height" ValidatesOnNotifyDataErrors="True" ValidatesOnDataErrors="True" NotifyOnValidationError="True"> <Binding.ValidationRules> <local:NumericValidationRule ValidationType="Positive_Float"/> </Binding.ValidationRules> </Binding> </TextBox>
cs中
public class NumericValidationRule : ValidationRule { public string ValidationType { get; set; } public override ValidationResult Validate(object value, CultureInfo cultureInfo) { string strValue = Convert.ToString(value); if (string.IsNullOrEmpty(strValue)) return new ValidationResult(false, $"Please enter a positive number"); switch (ValidationType) { case "Positive_Float": bool canConvert = float.TryParse(strValue, out float floatVal); if (canConvert) canConvert = floatVal > 0; return canConvert ? new ValidationResult(true, null) : new ValidationResult(false, $"Please enter a positive floating point number"); default: throw new InvalidCastException($"{ValidationType} is not supported"); } } }
10. MVVM 基本
internal class ViewModel : INotifyPropertyChanged{} + #region Property Changed // EventHandlers public event PropertyChangedEventHandler PropertyChanged; private void propertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion
11. File
(1) write to file
newline: private readonly string newLine = $"{Environment.NewLine}";
generateFileName:
private string GenerateFullName() { // C:UserssaberAppDataRoamingWeek5 string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Week5"); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } return Path.Combine(filePath, FILENAME); }
fileAppend: File.AppendAllText(fullName, $"New run starting at {DateTime.Now:MMMM dd, yyyy HH:mm:ss}{newLine}");
(1) read file
1. file放在文件哪里?
2. string text = File.ReadAllText("eggs.txt");
12. converter
在 <Window.Resources> 中声明 <local:MessageConverter x:Key="MessageConverter"/>
根据messagecode值不同,改变content
xaml:
Content="{Binding MessageCode, Converter={StaticResource MessageConverter}}"
如果带有参数: Content="{Binding IsMetric, Converter={StaticResource InputLabelConverter},ConverterParameter=Weight}"
cs:
public enum MessageCodes { NO_VALUES, UNDER_WEIGHT, NORMAL_WEIGHT, OVER_WEIGHT, OBESE }
public class BMIConverter : IValueConverter{} 其中 public class MessageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string message = ""; switch ((MessageCodes)value) { case MessageCodes.NO_VALUES: message = "Please enter a value for height and weight."; break; case MessageCodes.UNDER_WEIGHT: message = "A person with this BMI is under weight."; break; case MessageCodes.NORMAL_WEIGHT: message = "A person with this BMI is normal weight."; break; case MessageCodes.OVER_WEIGHT: message = "A person with this BMI is over weight."; break; case MessageCodes.OBESE: message = "A person with this BMI is obese."; break; } return message; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
13. visibility
lblMsg.Visibility = Visibility.Hidden;
lblBmi.Visibility = Visibility.Visible;
14. 类型转换,并且返回是否转换成功 double.TryParse(txtHeight.Text, out double height);
xaml
1. stackPanel: 布局Button
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right"> <Button Name="DoIt" Content="Do It" FontSize="35" MinWidth="150" Margin="10,5" Click="doIt_Click"></Button> <Button Name="Save" Content="Save" FontSize="35" MinWidth="150" Margin="10,5" Click="save_Click"></Button> </StackPanel>
viewbox - RadioButton
<!-- Viewbox allows for changing the size of the radio buttons as well as the text--> <Viewbox Margin="10" Height="25" Grid.Column="1" Grid.ColumnSpan="2" HorizontalAlignment="Left"> <StackPanel Orientation="Horizontal" Grid.Column="1" Grid.ColumnSpan="2"> <RadioButton Name="rbImp" Content="Imperial" HorizontalAlignment="Left" VerticalAlignment="Center" Checked="RbImp_Checked"/> <RadioButton Name="rbMetric" Content="Metric" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="45 0 0 0" Checked="RbMetric_Checked"/> </StackPanel> </Viewbox>
viewbox - CheckBox
<Viewbox MaxHeight="60"> <CheckBox IsChecked="{Binding Open}" Name="Open" Margin="5" Content="Open the box"></CheckBox> </Viewbox>
ListBox
<ListBox Margin="5" FontSize="30" SelectedIndex="{Binding Index}" > <!-- SelectionChanged="ListBox_SelectionChanged"--> <ListBoxItem>Hot Dog</ListBoxItem> <ListBoxItem>Steak</ListBoxItem> <ListBoxItem>Baloney</ListBoxItem> <ListBoxItem>Quinoa</ListBoxItem> </ListBox>
ListBox 中按照格式呈现
<ListBox Grid.Row="0" ItemsSource="{Binding Eggs}" Margin="5" FontSize="20" HorizontalContentAlignment="Stretch"> <ListBox.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Label Grid.Column="0" Content="{Binding Farm}"/> <Label Grid.Column="1" Content="{Binding Color}"/> <Label Grid.Column="2" Content="{Binding Size}"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
2. slider binding textbox
<Slider x:Name="sliderInterestInput" Value="{Binding InterestInput}" Minimum="0" Maximum="10" Grid.Row="1" Grid.Column="1" Width="500" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBox Text="{Binding ElementName=sliderInterestInput, Path=Value}" Grid.Column="2" Grid.Row="1" Width="200" Height="50" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="20"/>
3.
TextWrapping="Wrap"
HorizontalContentAlignment="Center"
HorizontalAlignment="Center"
BorderThickness="5"
BorderBrush="#FF00A2FF"
IsReadOnly="True"
4. 展示List
<ListView Grid.Row="2" Grid.Column="1" ItemsSource="{Binding Games}" Grid.RowSpan="6" VerticalAlignment="Center" HorizontalAlignment="Center" Width="560" Height="390" UseLayoutRounding="False"> <ListView.View> <GridView> <GridViewColumn Header="No" Width="30" DisplayMemberBinding="{Binding Number}"/> <GridViewColumn Header="History" Width="470" DisplayMemberBinding="{Binding Guesses}"/> <GridViewColumn Header="Answer" Width="50" DisplayMemberBinding="{Binding Answer}"/> </GridView> </ListView.View> </ListView>
cs处格式化format
vm.Display = $"{vm.PresentValue:#0.00}={vm.FutureValue:#0.00}/(1+{vm.Rate:#0.00})^{vm.Year}";
或者:
Result.Content = $"{resultNumber:n1}"; // 保留一位
或者:
float bmi = (float)value; if (bmi > 0) display = bmi.ToString("0.#");
或者:
total.ToString("n1");
xaml处格式化
<Label Content="{Binding Path=DateAsked}" ContentString="{}{0:yyyy/MM/dd HH:mm:ss}" />
TextBox中格式化,fn中的n表示小数点后位数
Text="{Binding TR0, Mode=TwoWay,StringFormat='f2'}"
5. style Template
<Window.Resources> <Style x:Key="TextStyle" TargetType="Label"> <Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="FontFamily" Value="Century Gothic"/> <Setter Property="FontSize" Value="30"/> <Setter Property="FontWeight" Value="Bold"/> </Style> </Window.Resources>
Style="{StaticResource TextStyle}"
6. background
<Grid.Background> <ImageBrush ImageSource="bg.png"/> </Grid.Background>
cs 中设置background
public MainWindow() { InitializeComponent(); //TheGrid.Background = new SolidColorBrush(Colors.AliceBlue); TheGrid.Background = new SolidColorBrush(Color.FromArgb(128, 0x2e, 0x4e, 0x6e)); //TheGrid.Background = new LinearGradientBrush(Colors.AliceBlue, Colors.Bisque, 45); }
纯picture:
<Image Grid.ColumnSpan="2" Grid.RowSpan="2" Source="images/landscape.jpg" Stretch="Fill"></Image>
用border延伸,并设置background:渐变(?还能这样
<Border Grid.Row="0" Grid.RowSpan="5" Grid.Column="0" Grid.ColumnSpan="4"> <Border.Background> <LinearGradientBrush EndPoint="0.01,1" StartPoint="0.6,0"> <GradientStop Color="#a29bfe" Offset="0" /> <GradientStop Color="White" Offset="1" /> </LinearGradientBrush> </Border.Background> </Border>
7. TextBlock & label
Labels usually support single line text output while the TextBlock is intended for multiline text display.
For example in wpf TextBlock has a property TextWrapping which enables multiline input; Label does not have this.
8. ToolTip
<wpfTool:UIntegerUpDown Grid.Row="1" Grid.Column="1" Margin="5" Value="{Binding Hours}"/>
集合
1. example
when ItemsSource="{Binding Eggs}"
vm.cs 中有 public ObservableCollection<Egg> Eggs { get; set; } = new ObservableCollection<Egg>();
Egg.cs:
public enum Sizes { PeeWee, Small, Medium, Large, XLarge } public enum Colors { White, Brown, Speckled } public class Egg { public string Farm { get; set; } public Sizes Size { get; set; } public Colors Color { get; set; } public override string ToString() { return $"{Farm} | {Size} | {Color}"; } }
读取文件后分割处理list
string[] lines = text.Split(new char[] { ' ', ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { string[] props = line.Split(new char[] { ',' }); Egg egg = new Egg { Farm = props[0].Trim(), Color = (Colors)int.Parse(props[1].Trim()), Size = (Sizes)int.Parse(props[2].Trim()) }; Eggs.Add(egg); }
2. Array
1. single-dimension
string[] stringArray = new string[6]; // initialization string[] weekDays = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // avoid new int[] array2 = { 1, 3, 5, 7, 9 };
2. multi-dimensional
int[,] array = new int[4, 2]; int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // The same array with dimensions specified. int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
3. jagged arrays
int[][] jaggedArray = new int[3][]; // initialization jaggedArray[0] = new int[5]; jaggedArray[1] = new int[4]; jaggedArray[2] = new int[2]; // or int[][] jaggedArray2 = new int[][] { new int[] { 1, 3, 5, 7, 9 }, new int[] { 0, 2, 4, 6 }, new int[] { 11, 22 } }; // or more simple int[][] jaggedArray3 = { new int[] { 1, 3, 5, 7, 9 }, new int[] { 0, 2, 4, 6 }, new int[] { 11, 22 } };
3. List
List<int> ls = new List<int> { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; ls.Add(42); ls.AddRange(ys); // 添加到List的末尾 ls.Clear();
4. Dictionary<Tkey,Tvalue>
Dictionary<string, int> ds = new Dictionary<string, int>(); ds.Add("first", 7); // ds.Add("first", 9); // this will throw an exception // int d = ds["third"]; // throw an exception // so we use ds.TryGetValue("first", out int val);