详解WPF中用户控件和自定义控件的使用
WPF中的控件可以根据我们的需要进行自定义,这就涉及到两种方式:用户控件和自定义控件。本文将详细讲解这两种方式的使用方法。
用户控件
用户控件是由多个控件组成的可重用控件。我们可以将多种原生控件组合在一起,用 C# 或 VB.NET 编写代码,从而构建出一个新的用户控件。在开发过程中,用户控件可以像其他控件那样使用、放置、绑定和样式化。
1. 创建用户控件
在Visual Studio中,可以通过以下步骤创建用户控件:
- 在项目中添加一个新的用户控件,例如MainControl.xaml
- 在XAML代码中定义控件的布局结构,例如:
<UserControl x:Class="Demo.MainControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid Background="White">
<StackPanel>
<Button Content="Click me" Margin="10"/>
<TextBox Text="Input here" Margin="10"/>
</StackPanel>
</Grid>
</UserControl>
- 在代码文件中定义该控件的行为,例如:
public partial class MainControl : UserControl
{
public MainControl()
{
InitializeComponent();
}
public string InputText
{
get { return txtInput.Text; }
set { txtInput.Text = value; }
}
private void button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello world!");
}
}
2. 使用用户控件
使用用户控件时,要将其添加到WPF窗口中。可以通过以下步骤实现:
- 在窗口中添加对用户控件的引用The DLL file containing the UserControl.
- 在窗口中添加用户控件的命名空间引用。
- 在窗口中添加用户控件标记,例如:
<Window x:Class="Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Demo"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:MainControl InputText="This is a test."/>
</Grid>
</Window>
自定义控件
自定义控件是继承自原生控件的新控件。它们填补了WPF控件集中未提供的缺口,或为特定场景提供了定制化的交互模式。自定义控件可以在 XAML 中布局,可以由自己的样式和模板,处于与原生控件相同的级别。
1. 创建自定义控件
在Visual Studio中,可以通过以下步骤创建自定义控件:
- 在项目中添加一个新的自定义控件,例如MyButton.cs
- 将 MyButton 类声明为 public 并继承自 Button,例如:
public class MyButton : Button
{
static MyButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
}
}
- 创建控件模板,这里只是一个最简单的样例:
<Style TargetType="{x:Type local:MyButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyButton}">
<Border Background="LightBlue" BorderBrush="Navy" BorderThickness="2" CornerRadius="10">
<ContentPresenter Margin="8"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2. 使用自定义控件
使用自定义控件时,可以像原生控件一样使用。在XAML中添加自定义控件标记即可。例如:
<Window x:Class="Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Demo"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:MyButton Content="Click me"/>
</Grid>
</Window>
示例说明
示例1:用用户控件实现一个带搜索框的列表视图
- 在项目中添加一个新的用户控件,例如SearchableListView.xaml
- 在XAML代码中定义控件的布局结构,例如:
<UserControl x:Class="Demo.SearchableListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBox x:Name="txtSearch" Margin="10" PlaceholderText="Search..."/>
<ListView x:Name="lvItems" Margin="10" Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageUrl}" Width="100"/>
<TextBlock Text="{Binding Title}" Margin="10"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</UserControl>
- 在代码文件中定义该控件的行为,例如:
public partial class SearchableListView : UserControl
{
public SearchableListView()
{
InitializeComponent();
}
public ObservableCollection<MyData> ItemsSource
{
get { return (ObservableCollection<MyData>)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<MyData>), typeof(SearchableListView), new PropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SearchableListView view = d as SearchableListView;
view.lvItems.ItemsSource = e.NewValue as ObservableCollection<MyData>;
}
private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
{
string keyword = txtSearch.Text.Trim();
if (string.IsNullOrEmpty(keyword))
{
lvItems.ItemsSource = ItemsSource;
}
else
{
lvItems.ItemsSource = ItemsSource.Where(t => t.Title.Contains(keyword));
}
}
}
- 在窗口中使用该控件
<Window x:Class="Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Demo"
Title="MainWindow" Height="450" Width="800">
<local:SearchableListView ItemsSource="{Binding ListViewData}"/>
</Window>
示例2:用自定义控件实现一个时钟控件
- 在项目中添加一个新的自定义控件,例如Clock.cs
- 将 Clock 类声明为 public 并继承自 Control,例如:
public class Clock : Control
{
static Clock()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Clock), new FrameworkPropertyMetadata(typeof(Clock)));
}
public override void OnApplyTemplate()
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
base.OnApplyTemplate();
}
void timer_Tick(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
SetValue(HoursProperty, now.Hour);
SetValue(MinutesProperty, now.Minute);
SetValue(SecondsProperty, now.Second);
}
public int Hours
{
get { return (int)GetValue(HoursProperty); }
private set { SetValue(HoursProperty, value); }
}
public static readonly DependencyProperty HoursProperty =
DependencyProperty.Register("Hours", typeof(int), typeof(Clock), new PropertyMetadata(0));
public int Minutes
{
get { return (int)GetValue(MinutesProperty); }
private set { SetValue(MinutesProperty, value); }
}
public static readonly DependencyProperty MinutesProperty =
DependencyProperty.Register("Minutes", typeof(int), typeof(Clock), new PropertyMetadata(0));
public int Seconds
{
get { return (int)GetValue(SecondsProperty); }
private set { SetValue(SecondsProperty, value); }
}
public static readonly DependencyProperty SecondsProperty =
DependencyProperty.Register("Seconds", typeof(int), typeof(Clock), new PropertyMetadata(0));
}
- 创建控件模板,例如:
<Style TargetType="{x:Type local:Clock}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Clock}">
<Canvas Width="200" Height="200">
<Ellipse Stroke="Blue" StrokeThickness="2" Width="180" Height="180" Canvas.Left="10" Canvas.Top="10"/>
<Line X1="100" Y1="40" X2="100" Y2="100" Stroke="Black" StrokeThickness="4" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<RotateTransform Angle="{Binding Hours, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource HourConverter}}"/>
</Line.RenderTransform>
</Line>
<Line X1="100" Y1="20" X2="100" Y2="100" Stroke="Black" StrokeThickness="3" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<RotateTransform Angle="{Binding Minutes, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource MinuteConverter}}"/>
</Line.RenderTransform>
</Line>
<Line X1="100" Y1="20" X2="100" Y2="100" Stroke="Red" StrokeThickness="2" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<RotateTransform Angle="{Binding Seconds, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SecondConverter}}"/>
</Line.RenderTransform>
</Line>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
- 在窗口中使用该控件
<Window x:Class="Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Demo"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:Clock/>
</Grid>
</Window>
以上就是WPF中用户控件和自定义控件的使用方法详解,希望对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解WPF中用户控件和自定义控件的使用 - Python技术站