WPF笔记汇总之工程结构与控件基础

WPF结构及控件基础

关于WPF的教程很少,网上虽然有很多,但都杂乱无章,而且千篇一律的分块讲解,令人难以有耐心看完。最近得闲,准备总结汇总一套WPF的学习笔记,类似教程吧,这篇主要讲WPF的项目搭建及控件基础。

1. 项目结构与XAML

1.1 项目结构基础

首先创建一个WPF应用程序项目,这里不再赘述,重点描述项目文件。
MainWindow.xaml:主窗体的XAML脚本
MainWindow.xaml.cs:主窗体的后置代码
App.xaml:应用程序定义的起点
App.xaml.cs:App.xaml的后置代码文件,其中 StartupUri=“MainWindow.xaml” 表示启动的主窗体,也可以写后台事件代码替换,这在使用启动命令行参数时灰常有用。举个例子如下:使用Startup属性取代StartupUri,并在后置代码中增加对应的Application_Startup事件。

App.xaml脚本代码

<Application x:Class="WpfStudy.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfStudy"
			 Startup="Application_Startup">
    <Application.Resources>
         
    </Application.Resources>
</Application>

App.xaml后置逻辑代码

public partial class App : Application
{
	private void Application_Startup(object sender, StartupEventArgs e)
	{
		MainWindow wnd = new MainWindow();
		if (e.Args.Length == 1)
			MessageBox.Show("Now opening file: \n\n" + e.Args[0]);
		wnd.Show();
	}
}

可以在 调试->启动选项->命令行参数 中填写参数。

1.2 XAML基础

非常类似HTML,是一种以XML文档结构为基础的描述控件UI的脚本语言。

<StackPanel Margin="10" Name="pnlMain" 
		MouseUp="pnlMainGrid_MouseUp" 
		Background="LightBlue">

<Button>
	<Button.FontWeight>Bold</Button.FontWeight>
	<Button.Content>
		<WrapPanel>
			<TextBlock Foreground="Blue">Multi</TextBlock>
			<TextBlock Foreground="Red">Color</TextBlock>
			<TextBlock>Button</TextBlock>
		</WrapPanel>
	</Button.Content>
</Button>

<Button FontWeight="Bold">
	<WrapPanel>
		<TextBlock Foreground="Blue">Multi</TextBlock>
		<TextBlock Foreground="Red">Color</TextBlock>
		<TextBlock>Button</TextBlock>
	</WrapPanel>
</Button>

</StackPanel>

后置代码实现实例

public MainWindow()
{
	InitializeComponent();
	
	Button btn = new Button();
	btn.FontWeight = FontWeights.Bold;
	WrapPanel pnl = new WrapPanel();
	TextBlock txt = new TextBlock();
	txt.Text = "Multi";
	txt.Foreground = Brushes.Blue;
	pnl.Children.Add(txt);
	txt = new TextBlock();
	txt.Text = "Color";
	txt.Foreground = Brushes.Red;
	pnl.Children.Add(txt);
	txt = new TextBlock();
	txt.Text = "Button";
	pnl.Children.Add(txt);
	btn.Content = pnl;
	pnlMain.Children.Add(btn);

	this.pnlMain.MouseUp += new MouseButtonEventHandler(pnlMainGrid_MouseUp);
}

private void pnlMainGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
	MessageBox.Show("You clicked me at " + e.GetPosition(this).ToString());
}

2. 资源使用初步

简单的理解,资源在WPF中就是类似网页中的CSS样式表的存在。

2.1 窗体中样式资源

类似作用域的概念,就是窗体内可以使用这个资源

<Window.Resources>
	<sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
</Window.Resources>
<StackPanel Margin="10">
	<TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" />
	<TextBlock>Just another "
		<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!
	</TextBlock>
</StackPanel>
2.2 区域内的样式资源

在某个区域控件内有效

<StackPanel Margin="10">
	<StackPanel.Resources>
		<sys:String x:Key="content">Hello WPF!</sys:String>
	</StackPanel.Resources>
	<TextBox Text="{StaticResource content}" />
</StackPanel>
2.3 应用程序范围资源

App.xaml内配置的资源,在全部应用程序范围内都有效

<Application x:Class="WpfStudy.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfStudy" xmlns:sys="clr-namespace:System;assembly=mscorlib"
			 StartupUri="MainWindow.xaml">
    <Application.Resources>
		<sys:String x:Key="appTitle">I like WPF!</sys:String>
	</Application.Resources>
</Application>

在窗体中使用

<StackPanel Margin="10">
	<Label Content="{StaticResource appTitle}"></Label>
</StackPanel>

后台代码中使用

string appTitleStr = Application.Current.FindResource("appTitle").ToString();
MessageBox.Show(appTitleStr);

3. 全局异常处理

在全域内就是在应用程序级捕获所有未处理的异常,也是在App.xaml中处理:
在App.xaml中加入 DispatcherUnhandledException属性。

<Application x:Class="WpfStudy.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfStudy" xmlns:sys="clr-namespace:System;assembly=mscorlib"
			 DispatcherUnhandledException="Application_DispatcherUnhandledException"
			 StartupUri="MainWindow.xaml">
    <Application.Resources>
		<sys:String x:Key="appTitle">I like WPF!</sys:String>
	</Application.Resources>
</Application>

在App.xaml.cs中编写事件捕获代码

public partial class App : Application
{
	private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
	{
		MessageBox.Show("An unhandled exception just occurred: " + 
			e.Exception.Message, "Exception Sample", 
			MessageBoxButton.OK, MessageBoxImage.Warning);
		e.Handled = true;
	}
}

4. 基础控件

4.1 TextBlock

类似lable标签,但可以显示多行文字,而且文本显示格式更丰富。其中的Run元素允许你使用所有可以在Span元素中使用的属性来定义文本的样式。但相对于Span可以包含其他行内元素,Run只能包含纯文本。Span元素本身并没有任何默认的显示效果,但允许你设置几乎所有的显示效果,包括字体大小、字体样式和粗细,以及背景和前景颜色等等。它能包含其他行内元素在其中,使得构建更为复杂的文本以及样式非常容易。

<StackPanel>
	<!-- LineBreak 手动换行-->
	<TextBlock Margin="10" Foreground="Red">
		This is a TextBlock control<LineBreak />
		with multiple lines of text.
	</TextBlock>
	<!-- TextTrimming WordEllipsis/CharacterEllipsis提示省略...-->
	<TextBlock Margin="10" TextTrimming="CharacterEllipsis" Foreground="Green">
		This is a TextBlock control with text that may not be rendered completely, which will be indicated with an ellipsis.
	</TextBlock>
	<!-- TextWrapping 自动换行-->
	<TextBlock Margin="10" TextWrapping="Wrap" Foreground="Blue">
		This is a TextBlock control with automatically wrapped text, using the TextWrapping property.
	</TextBlock>
</StackPanel>
<!--内联字体样式-->
<TextBlock Margin="10" TextWrapping="Wrap">
	TextBlock with <Bold>bold</Bold>, <Italic>italic</Italic> and <Underline>underlined</Underline> text.
</TextBlock>
<!--超链接-->
<TextBlock Margin="10" TextWrapping="Wrap">
	This text has a 
	<Hyperlink RequestNavigate="Hyperlink_RequestNavigate" 
							   NavigateUri="https://www.google.com">link</Hyperlink> in it.
</TextBlock>
<!--Span元素格式化文本-->
<TextBlock Margin="10" TextWrapping="Wrap">
	This <Span FontWeight="Bold">is</Span> a
	<Span Background="Silver" Foreground="Maroon">TextBlock</Span>
	with <Span TextDecorations="Underline">several</Span>
	<Span FontStyle="Italic">Span</Span> elements,
	<Span Foreground="Blue">
		using a <Bold>variety</Bold> of <Italic>styles</Italic>
	</Span>.
</TextBlock>

后置代码格式化文本

TextBlock tb = new TextBlock();
tb.TextWrapping = TextWrapping.Wrap;
tb.Margin = new Thickness(10);
tb.Inlines.Add("An example on ");
tb.Inlines.Add(new Run("the TextBlock control ") { FontWeight = FontWeights.Bold });
tb.Inlines.Add("using ");
tb.Inlines.Add(new Run("inline ") { FontStyle = FontStyles.Italic });
tb.Inlines.Add(new Run("text formatting ") { Foreground = Brushes.Blue });
tb.Inlines.Add("from ");
tb.Inlines.Add(new Run("Code-Behind") { TextDecorations = TextDecorations.Underline });
tb.Inlines.Add(".");
this.Content = tb;
4.2 Lable

Label使用的是Content属性而不是Text属性。这是因为Label内部可以放置任意类型的控件而不仅仅是文本。

<StackPanel>
	<Label Content="This is a Label control." />
	<!--按住[Alt]键,然后按N和M.则可以看到两个文本框之间的焦点移动-->
	<Label Target="{Binding ElementName=txtName}">
		<StackPanel Orientation="Horizontal">
			<Image Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_green.png" />
			<AccessText Text="_Name:" />
		</StackPanel>
	</Label>
	<TextBox Name="txtName" />
	<Label Target="{Binding ElementName=txtMail}">
		<StackPanel Orientation="Horizontal">
			<Image Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_blue.png" />
			<AccessText Text="_Mail:" />
		</StackPanel>
	</Label>
	<TextBox Name="txtMail" />
</StackPanel>
4.3 TextBox

TextBox控件是WPF中最基本的文字输入控件。它允许最终用户在一行、对话输入、或多行编写,就像是个编辑器。

<StackPanel>
	<TextBox Text="Hello, world!"  Margin="10"/>
	<!--多行文本,SpellCheck类中名为IsEnabled的附加属性,
	该属性仅支持对父控件进行拼写检查,
	以及Language属性,
	该属性指示拼写检查器使用的语言。-->
	<TextBox AcceptsReturn="True" TextWrapping="Wrap" Margin="10"
			 Text="Have a look at the Table of contents to the right, 
			 where all the chapters are listed and be sure to come back regularly,
			 as we will keep adding new chapters to it. 
			 We hope that this tutorial will get you started properly on WPF. "
			 SpellCheck.IsEnabled="True" Language="en-US" />
	<!--选择属性-->
	<TextBox SelectionChanged="TextBox_SelectionChanged" Margin="10" />
	<TextBox Name="txtStatus" AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="True" Margin="20"/>
</StackPanel>

选择属性的后置代码

private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
	TextBox textBox = sender as TextBox;
	txtStatus.Text = "Selection starts at character #" + textBox.SelectionStart + Environment.NewLine;
	txtStatus.Text += "Selection is " + textBox.SelectionLength + " character(s) long" + Environment.NewLine;
	txtStatus.Text += "Selected text: '" + textBox.SelectedText + "'";
}
4.4 Button

按钮非常重要,WPF里的按钮几乎可以自己随意定制和添加各种格式样式

<Window.Resources>
	<Style TargetType="{x:Type Button}">
		<Setter Property="Padding" Value="5,2"/>
	</Style>
</Window.Resources>
<StackPanel>
	<Button Margin="20" Click="HelloWorldButton_Click">Hello, World!</Button>
	<Button Margin="20" Background="Beige" Foreground="Blue" FontWeight="Bold">Formatted Button</Button>
	<!--复杂按钮-->
	<Button Margin="10">
		<StackPanel Orientation="Horizontal" >
			<TextBlock>Formatted</TextBlock>
			<TextBlock Foreground="Blue" FontWeight="Bold" Margin="2,0">Button</TextBlock>
			<TextBlock Foreground="Gray" FontStyle="Italic">[Various]</TextBlock>
		</StackPanel>
	</Button>
	<!--图片按钮-->
	<Button Padding="5" Margin="10">
		<StackPanel Orientation="Horizontal">
			<Image Source="me.png" />
			<TextBlock Margin="5,0">Help</TextBlock>
		</StackPanel>
	</Button>
	<!--填充按钮-->
	<Button Padding="5,2">Hello, World!</Button>
</StackPanel>
4.5 CheckBox

CheckBox 控件就是一个复选框,允许用户启用或禁用一个选项,这通常在逻辑代码中对应一个布尔值。

<StackPanel Margin="10">
		<Label FontWeight="Bold">Application Options</Label>
		<CheckBox>Enable feature ABC</CheckBox>
		<CheckBox IsChecked="True">Enable feature XYZ</CheckBox>
		<CheckBox>Enable feature WWW</CheckBox>
	<!--自定义内容-->
	<Label FontWeight="Bold">Application Options</Label>
	<CheckBox>
		<TextBlock>
			Enable feature <Run Foreground="Green" FontWeight="Bold">ABC</Run>
		</TextBlock>
	</CheckBox>
	<CheckBox IsChecked="True">
		<WrapPanel>
			<TextBlock>
				Enable feature <Run FontWeight="Bold">XYZ</Run>
			</TextBlock>
			<Image Source="/images/file.png" Width="16" Height="16" Margin="5,0" />
		</WrapPanel>
	</CheckBox>
	<CheckBox>
		<TextBlock>
			Enable feature <Run Foreground="Blue" TextDecorations="Underline" FontWeight="Bold">WWW</Run>
		</TextBlock>
	</CheckBox>
	
	<!--第三种状态-->
	<Label FontWeight="Bold">Application Options</Label>
	<StackPanel Margin="10,5">
		<CheckBox IsThreeState="True" Name="cbAllFeatures" 
				  Checked="cbAllFeatures_CheckedChanged" 
				  Unchecked="cbAllFeatures_CheckedChanged">Enable all</CheckBox>
		<StackPanel Margin="20,5">
			<CheckBox Name="cbFeatureAbc" 
					  Checked="cbFeature_CheckedChanged" 
					  Unchecked="cbFeature_CheckedChanged">Enable feature ABC</CheckBox>
			<CheckBox Name="cbFeatureXyz" IsChecked="True" 
					  Checked="cbFeature_CheckedChanged" 
					  Unchecked="cbFeature_CheckedChanged">Enable feature XYZ</CheckBox>
			<CheckBox Name="cbFeatureWww" 
					  Checked="cbFeature_CheckedChanged" 
					  Unchecked="cbFeature_CheckedChanged">Enable feature WWW</CheckBox>
		</StackPanel>
	</StackPanel>
</StackPanel>

后置事件代码

private void cbAllFeatures_CheckedChanged(object sender, RoutedEventArgs e)
{
	bool newVal = (cbAllFeatures.IsChecked == true);
	cbFeatureAbc.IsChecked = newVal;
	cbFeatureXyz.IsChecked = newVal;
	cbFeatureWww.IsChecked = newVal;
}

private void cbFeature_CheckedChanged(object sender, RoutedEventArgs e)
{
	cbAllFeatures.IsChecked = null;
	if ((cbFeatureAbc.IsChecked == true) && (cbFeatureXyz.IsChecked == true) && (cbFeatureWww.IsChecked == true))
		cbAllFeatures.IsChecked = true;
	if ((cbFeatureAbc.IsChecked == false) && (cbFeatureXyz.IsChecked == false) && (cbFeatureWww.IsChecked == false))
		cbAllFeatures.IsChecked = false;
}
4.6 RadioButton

RadioButton 单选按钮,该控件允许你向用户提供一列可能的选项,而同时只允许选中一个。

<StackPanel Margin="10">
	<!--分组单选-->
	<Label FontWeight="Bold">Are you ready?</Label>
	<RadioButton GroupName="ready">Yes</RadioButton>
	<RadioButton GroupName="ready">No</RadioButton>
	<RadioButton GroupName="ready" IsChecked="True">Maybe</RadioButton>

	<Label FontWeight="Bold">Male or female?</Label>
	<RadioButton GroupName="sex">Male</RadioButton>
	<RadioButton GroupName="sex">Female</RadioButton>
	<RadioButton GroupName="sex" IsChecked="True">Not sure</RadioButton>
	
	<!--自定义内容-->
	<StackPanel Margin="10">
		<Label FontWeight="Bold">Are you ready?</Label>
		<RadioButton>
			<WrapPanel>
				<Image Source="/images/file.png" Width="16" Height="16" Margin="0,0,5,0" />
				<TextBlock Text="Yes" Foreground="Green" />
			</WrapPanel>
		</RadioButton>
		<RadioButton Margin="0,5">
			<WrapPanel>
				<Image Source="/images/file.png" Width="16" Height="16" Margin="0,0,5,0" />
				<TextBlock Text="No" Foreground="Red" />
			</WrapPanel>
		</RadioButton>
		<RadioButton IsChecked="True">
			<WrapPanel>
				<Image Source="/images/file.png" Width="16" Height="16" Margin="0,0,5,0" />
				<TextBlock Text="Maybe" Foreground="Gray" />
			</WrapPanel>
		</RadioButton>
	</StackPanel>

</StackPanel>
4.7 PasswordBox

密码文本框控件

<StackPanel Margin="10">
	<Label>Text:</Label>
	<TextBox />
	<Label>Password:</Label>
	<PasswordBox />
	<PasswordBox MaxLength="6" PasswordChar="X"/>
</StackPanel>
4.8 Image

显示图片用的控件

<StackPanel Margin="10">
	<Image Name="imgDynamic"  Source="/images/me.png" Stretch="None" />
</StackPanel>

后置代码加载图片

Uri resourceUri = new Uri("/Images/white_bengal_tiger.jpg", UriKind.Relative);
imgDynamic.Source = new BitmapImage(resourceUri);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值