WPF - Tương tác
Trong WPF, một tương tác cho biết cách một chế độ xem tương tác với các điều khiển nằm trong chế độ xem đó. Các tương tác phổ biến nhất được biết đến có hai loại:
- Behaviors
- Kéo và thả
Hành vi cư xử
Behaviors được giới thiệu với Expression Blend 3 có thể đóng gói một số chức năng vào một thành phần có thể tái sử dụng. Để thêm các hành vi bổ sung, bạn có thể đính kèm các thành phần này vào các điều khiển. Các hành vi cung cấp tính linh hoạt hơn để dễ dàng thiết kế các tương tác phức tạp của người dùng.
Hãy xem một ví dụ đơn giản trong đó hành vi ControlStoryBoardAction được gắn vào các điều khiển.
Tạo một dự án WPF mới với tên WPFBehavior.
Mã XAML sau đây tạo một hình elip và hai nút để điều khiển chuyển động của hình elip.
<Window
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:WPFBehaviors"
xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei = "http://schemas.microsoft.com/expression/2010/interactions"
x:Class = "WPFBehaviors.MainWindow"
mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
<Window.Resources>
<Storyboard x:Key = "Storyboard1" RepeatBehavior = "Forever" AutoReverse = "True">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty =
"(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.X)"
Storyboard.TargetName = "ellipse">
<EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "301.524"/>
<EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "2.909"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty =
"(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.Y)"
Storyboard.TargetName = "ellipse">
<EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "-0.485"/>
<EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
Storyboard.TargetName = "button">
<DiscreteObjectKeyFrame KeyTime = "0" Value = "Play"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
Storyboard.TargetName = "button1">
<DiscreteObjectKeyFrame KeyTime = "0" Value = "Stop"/>
<DiscreteObjectKeyFrame KeyTime = "0:0:2" Value = "Stop"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent = "FrameworkElement.Loaded">
<BeginStoryboard Storyboard = "{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Ellipse x:Name = "ellipse" Fill = "#FFAAAAC5" HorizontalAlignment = "Left"
Height = "50.901" Margin = "49.324,70.922,0,0" Stroke = "Black"
VerticalAlignment = "Top" Width = "73.684" RenderTransformOrigin = "0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Button x:Name = "button" Content = "Play" HorizontalAlignment = "Left" Height = "24.238"
Margin = "63.867,0,0,92.953" VerticalAlignment = "Bottom" Width = "74.654">
<i:Interaction.Triggers>
<i:EventTrigger EventName = "Click">
<ei:ControlStoryboardAction Storyboard = "{StaticResource Storyboard1}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button x:Name = "button1" Content = "Stop" HorizontalAlignment = "Left" Height = "24.239"
Margin = "160.82,0,0,93.922" VerticalAlignment = "Bottom" Width = "75.138">
<i:Interaction.Triggers>
<i:EventTrigger EventName = "Click">
<ei:ControlStoryboardAction ControlStoryboardOption = "Stop"
Storyboard = "{StaticResource Storyboard1}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</Window>
Khi bạn biên dịch và thực thi đoạn mã trên, nó sẽ tạo ra cửa sổ sau chứa một hình elip và hai nút.
Khi bạn nhấn nút phát, nó sẽ bắt đầu di chuyển từ trái sang phải và sau đó sẽ quay trở lại vị trí ban đầu. Nút dừng sẽ dừng chuyển động của hình elip.
Kéo và thả
Kéo và thả trên giao diện người dùng có thể nâng cao đáng kể hiệu quả và năng suất của ứng dụng. Có rất ít ứng dụng trong đó tính năng kéo và thả được sử dụng vì mọi người nghĩ rằng nó khó thực hiện. Ở một mức độ nào đó, rất khó để xử lý một tính năng kéo và thả, nhưng trong WPF, bạn có thể xử lý nó khá dễ dàng.
Hãy lấy một ví dụ đơn giản để hiểu nó hoạt động như thế nào. Chúng tôi sẽ tạo một ứng dụng trong đó bạn có thể kéo và thả màu từ hình chữ nhật này sang hình chữ nhật khác.
Tạo một dự án WPF mới với tên WPFDragAndDrop.
Kéo năm hình chữ nhật vào cửa sổ thiết kế và đặt các thuộc tính như được hiển thị trong tệp XAML sau đây.
<Window x:Class = "WPFDragAndDrop.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:WPFDragAndDrop"
mc:Ignorable = "d" Title = "MainWindow" Height = "402.551" Width = "604">
<Grid>
<Rectangle Name = "Target" Fill = "AliceBlue" HorizontalAlignment = "Left"
Height = "345" Margin = "10,10,0,0" Stroke = "Black"
VerticalAlignment = "Top" Width = "387" AllowDrop = "True" Drop = "Target_Drop"/>
<Rectangle Fill = "Beige" HorizontalAlignment = "Left" Height = "65"
Margin = "402,10,0,0" Stroke = "Black" VerticalAlignment = "Top"
Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>
<Rectangle Fill = "LightBlue" HorizontalAlignment = "Left" Height = "65"
Margin = "402,80,0,0" Stroke = "Black" VerticalAlignment = "Top"
Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>
<Rectangle Fill = "LightCoral" HorizontalAlignment = "Left" Height = "65"
Margin = "402,150,0,0" Stroke = "Black" VerticalAlignment = "Top"
Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>
<Rectangle Fill = "LightGray" HorizontalAlignment = "Left" Height = "65"
Margin = "402,220,0,0" Stroke = "Black" VerticalAlignment = "Top"
Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>
<Rectangle Fill = "OliveDrab" HorizontalAlignment = "Left" Height = "65"
Margin = "402,290,0,-7" Stroke = "Black" VerticalAlignment = "Top"
Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>
</Grid>
</Window>
Hình chữ nhật đầu tiên là hình chữ nhật mục tiêu, vì vậy người dùng có thể kéo màu từ hình chữ nhật khác sang hình chữ nhật mục tiêu.
Dưới đây là các sự kiện triển khai trong C # để kéo và thả.
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WPFDragAndDrop {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void Rect_MLButtonDown(object sender, MouseButtonEventArgs e) {
Rectangle rc = sender as Rectangle;
DataObject data = new DataObject(rc.Fill);
DragDrop.DoDragDrop(rc, data,DragDropEffects.Move);
}
private void Target_Drop(object sender, DragEventArgs e) {
SolidColorBrush scb = (SolidColorBrush)e.Data.GetData(typeof(SolidColorBrush));
Target.Fill = scb;
}
}
}
Khi bạn chạy ứng dụng của mình, nó sẽ tạo ra cửa sổ sau.
Nếu bạn kéo một màu từ hình chữ nhật ở phía bên phải và thả nó vào hình chữ nhật lớn bên trái, bạn sẽ thấy hiệu ứng của nó ngay lập tức.
Hãy kéo cái thứ 4 từ phía bên phải.
Bạn có thể thấy rằng màu của hình chữ nhật mục tiêu đã thay đổi. Chúng tôi khuyên bạn nên thực thi mã trên và thử nghiệm với các tính năng của nó.