wpf一些例子
相关知识点:WPF - Adorner
WPF Diagram Designer
http://www.codeproject.com/Articles/484616/MVVM-Diagram-Designer
翻译好的
http://www.cnblogs.com/zhoujg/archive/2009/11/23/1608913.html
http://www.cnblogs.com/zhoujg/archive/2010/08/17/1801271.html
http://www.cnblogs.com/zhoujg/archive/2010/08/17/1801427.html
http://www.cnblogs.com/zhoujg/archive/2010/08/19/1801660.html
http://www.cnblogs.com/zhoujg/archive/2010/08/19/1801663.html
树状列表:
http://www.codeproject.com/Articles/30721/WPF-TreeListView-Control
Automatic Scrolling During Drag operation
http://www.codeproject.com/Articles/618014/Automatic-Scrolling-During-Drag-operation
MainWindow.xaml using System.Windows; using System.Windows.Input; namespace AutoDragScrollingDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public void EnableDragDemo(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { DragDrop.DoDragDrop(sender as DependencyObject, new object(), DragDropEffects.Move); } } } }
MainWindow.xml.cs using System.Windows; using System.Windows.Input; namespace AutoDragScrollingDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public void EnableDragDemo(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { DragDrop.DoDragDrop(sender as DependencyObject, new object(), DragDropEffects.Move); } } } }
AutoDragScrollingDemo.cs /* *This work is being distributed under the The Code Project Open License (CPOL) (http://www.codeproject.com/info/cpol10.aspx) along with all restrictions placed therein. *Attribution: *1. Source Article: http://www.codeproject.com/Articles/618014/Automatic-Scrolling-During-Drag-operation * Author: Amit Mittal (http://www.codeproject.com/Members/Amit_Mittal) */ using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Media; namespace AutoDragScrollingDemo { public class AutoDragScrollingProvider { public static readonly DependencyProperty EnableAutomaticScrollingProperty = DependencyProperty.RegisterAttached("EnableAutomaticScrolling", typeof(bool), typeof(AutoDragScrollingProvider), new PropertyMetadata(default(bool), OnEnableAutomaticScrollingChange)); public static bool GetEnableAutomaticScrolling(DependencyObject obj) { return (bool)obj.GetValue(EnableAutomaticScrollingProperty); } public static void SetEnableAutomaticScrolling(DependencyObject obj, bool value) { obj.SetValue(EnableAutomaticScrollingProperty, value); } public static readonly DependencyProperty UseLineScrollingForVerticalChange = DependencyProperty.RegisterAttached("UseLineScrollingForVerticalChange", typeof(bool), typeof(AutoDragScrollingProvider), new PropertyMetadata(default(bool))); public static bool GetUseLineScrollingForVerticalChange(DependencyObject obj) { return (bool)obj.GetValue(UseLineScrollingForVerticalChange); } public static void SetUseLineScrollingForVerticalChange(DependencyObject obj, bool value) { obj.SetValue(UseLineScrollingForVerticalChange, value); } public static readonly DependencyProperty UseLineScrollingForHorizontalChangeProperty = DependencyProperty.RegisterAttached("UseLineScrollingForHorizontalChange", typeof(bool), typeof(AutoDragScrollingProvider), new PropertyMetadata(default(bool))); public static bool GetUseLineScrollingForHorizontalChange(DependencyObject obj) { return (bool)obj.GetValue(UseLineScrollingForHorizontalChangeProperty); } public static void SetUseLineScrollingForHorizontalChange(DependencyObject obj, bool value) { obj.SetValue(UseLineScrollingForHorizontalChangeProperty, value); } private static readonly DependencyProperty _autoDragScrollingProviderProperty = DependencyProperty.RegisterAttached("_AutoDragScrollingProvider", typeof(AutoDragScrollingProvider), typeof(AutoDragScrollingProvider), new PropertyMetadata(default(AutoDragScrollingProvider))); private static void OnEnableAutomaticScrollingChange(DependencyObject d, DependencyPropertyChangedEventArgs e) { var uiElement = d as UIElement; if (uiElement != null) { if (true.Equals(e.NewValue)) { Debug.Assert(uiElement.GetValue(_autoDragScrollingProviderProperty) == null); var scrollingManager = new AutoDragScrollingProvider(); uiElement.PreviewDragEnter += scrollingManager.HandlePreviewDragMove; uiElement.PreviewDragOver += scrollingManager.HandlePreviewDragMove; uiElement.SetValue(_autoDragScrollingProviderProperty, scrollingManager); } else { var scrollingManager = uiElement.GetValue(_autoDragScrollingProviderProperty) as AutoDragScrollingProvider; if (scrollingManager != null) { uiElement.PreviewDragEnter -= scrollingManager.HandlePreviewDragMove; uiElement.PreviewDragOver -= scrollingManager.HandlePreviewDragMove; uiElement.SetValue(_autoDragScrollingProviderProperty, null); } } } } //this caching is to avid some redundant steps but may prove troublesome //if parent tree is dynamic which in most cases is not the case. private IScrollInfo _scrollInfo; private void HandlePreviewDragMove(object sender, DragEventArgs e) { if (_scrollInfo == null) { ScrollViewer parentScrollViewer = null; var parent = e.OriginalSource as DependencyObject; while (parent != null) { parentScrollViewer = parent as ScrollViewer; if (parentScrollViewer != null) { break; } parent = VisualTreeHelper.GetParent(parent); } if (parentScrollViewer != null) { parent = e.OriginalSource as DependencyObject; while (parent != null) { _scrollInfo = parent as IScrollInfo; if (_scrollInfo != null && _scrollInfo.ScrollOwner == parentScrollViewer) { break; } _scrollInfo = null; parent = VisualTreeHelper.GetParent(parent); } } Panel scrollablePanel = _scrollInfo as Panel; if (scrollablePanel != null) { Orientation? orientation = null; //Special case handling as stack panel does not support 'smooth scrolling' or in other words fractional offset changes if (scrollablePanel is StackPanel) { orientation = (Orientation)scrollablePanel.GetValue(StackPanel.OrientationProperty); } //VirtualizingStackPanel behaves like StackPanel only if it is not hosted in an ItemsControl else if (scrollablePanel is VirtualizingStackPanel && !scrollablePanel.IsItemsHost) { orientation = (Orientation)scrollablePanel.GetValue(VirtualizingStackPanel.OrientationProperty); } if (orientation != null) { if (orientation == Orientation.Horizontal) { SetUseLineScrollingForHorizontalChange(scrollablePanel, true); } else { SetUseLineScrollingForVerticalChange(scrollablePanel, true); } } } } UIElement scrollable = _scrollInfo as UIElement; if (scrollable != null) { var mousePos = e.GetPosition(scrollable); if (_scrollInfo.CanHorizontallyScroll) { var avgWidth = scrollable.RenderSize.Width / _scrollInfo.ViewportWidth; //translate to pixels if (mousePos.X < 20) { if (GetUseLineScrollingForHorizontalChange(scrollable)) { _scrollInfo.LineLeft(); } else { var delta = (mousePos.X - 20) / avgWidth; //translate back to original unit _scrollInfo.SetHorizontalOffset(_scrollInfo.HorizontalOffset + delta); } } else if (mousePos.X > (scrollable.RenderSize.Width - 20)) { if (GetUseLineScrollingForHorizontalChange(scrollable)) { _scrollInfo.LineRight(); } else { var delta = (mousePos.X + 20 - scrollable.RenderSize.Width) / avgWidth; //translate back to original unit _scrollInfo.SetHorizontalOffset(_scrollInfo.HorizontalOffset + delta); } } } if (_scrollInfo.CanVerticallyScroll) { var avgHeight = scrollable.RenderSize.Height / _scrollInfo.ViewportHeight; //translate to pixels if (mousePos.Y < 20) { if (GetUseLineScrollingForVerticalChange(scrollable)) { _scrollInfo.LineUp(); } else { var delta = (mousePos.Y - 20) / avgHeight; //translate back to original unit _scrollInfo.SetVerticalOffset(_scrollInfo.VerticalOffset + delta); } } else if (mousePos.Y > (scrollable.RenderSize.Height - 20)) { if (GetUseLineScrollingForVerticalChange(scrollable)) { _scrollInfo.LineDown(); } else { var delta = (mousePos.Y + 20 - scrollable.RenderSize.Height) / avgHeight; //translate back to original unit _scrollInfo.SetVerticalOffset(_scrollInfo.VerticalOffset + delta); } } } } } } }
另外一个scrollviewer内容拖拽,自动滚动的例子
http://www.codeproject.com/Tips/635510/WPF-Drag-Drop-Auto-scroll
学习资料
http://drwpf.com/blog/2008/03/25/itemscontrol-i-is-for-item-container/
http://drwpf.com/blog/2008/07/20/itemscontrol-g-is-for-generator/
http://drwpf.com/blog/category/itemscontrol/
http://drwpf.com/blog/category/itemscontrol/
http://www.cnblogs.com/Kation/archive/2013/05/02/xaml-contentproperty-collection.html
Copy ui into image
http://www.cnblogs.com/gnielee/archive/2010/12/17/copy-wpf-ui-to-clipboard.html
Drag And Drop
http://blogs.msdn.com/b/llobo/archive/2006/12/08/drag-drop-library.aspx
Copy Item in Canvas and paste to self or another Canvas
http://www.cnblogs.com/DebugLZQ/archive/2013/05/06/3062409.html.
http://www.codeproject.com/Tips/82990/XAML-Serialization
https://msdn.microsoft.com/zh-cn/library/system.windows.markup.xamlreader%28v=vs.110%29.aspx
Copy Paste Item in Canvas with Undo Redo
namespace CopyAndPasteInCanvas { public partial class Window1 : Window { private Rectangle rect; private double top = 20; private double left = 20; private Stack<Shape> undoStack = new Stack<Shape>(); private Stack<Shape> redoStack = new Stack<Shape>(); public Window1() { InitializeComponent(); CommandBinding pasteCmdBinding = new CommandBinding(); pasteCmdBinding.Command = ApplicationCommands.Paste; pasteCmdBinding.Executed += pasteCmdBinding_Executed; pasteCmdBinding.CanExecute += pasteCmdBinding_CanExecute; this.CommandBindings.Add(pasteCmdBinding); CommandBinding copyCmdBinding = new CommandBinding(); copyCmdBinding.Command = ApplicationCommands.Copy; copyCmdBinding.Executed += copyCmdBinding_Executed; copyCmdBinding.CanExecute += copyCmdBinding_CanExecute; this.CommandBindings.Add(copyCmdBinding); CommandBinding undoCmdBinding = new CommandBinding(); undoCmdBinding.Command = ApplicationCommands.Undo; undoCmdBinding.CanExecute += undoCmdBinding_CanExecute; undoCmdBinding.Executed += undoCmdBinding_Executed; this.CommandBindings.Add(undoCmdBinding); CommandBinding redoCmdBinding = new CommandBinding(); redoCmdBinding.Command = ApplicationCommands.Redo; redoCmdBinding.CanExecute += redoCmdBinding_CanExecute; redoCmdBinding.Executed += redoCmdBinding_Executed; this.CommandBindings.Add(redoCmdBinding); rect = new Rectangle(); rect.Width = 60; rect.Height = 60; rect.Fill = Brushes.Red; } private void undoCmdBinding_Executed(object sender, ExecutedRoutedEventArgs e) { Shape shape = undoStack.Pop(); RemoveShape(shape); } private void undoCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = undoStack.Count > 0; } private void redoCmdBinding_Executed(object sender, ExecutedRoutedEventArgs e) { Shape shape = redoStack.Pop(); AddShape(shape); } private void redoCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = redoStack.Count > 0; } private void pasteCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = Clipboard.ContainsText(TextDataFormat.Xaml); } private void copyCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } private void copyCmdBinding_Executed(object sender, ExecutedRoutedEventArgs e) { string xaml = XamlWriter.Save(rect); Clipboard.SetText(xaml, TextDataFormat.Xaml); } private void pasteCmdBinding_Executed(object sender, ExecutedRoutedEventArgs e) { string xaml = Clipboard.GetText(TextDataFormat.Xaml); if (xaml != null) { using (MemoryStream stream = new MemoryStream(xaml.Length)) { using (StreamWriter sw = new StreamWriter(stream)) { sw.Write(xaml); sw.Flush(); stream.Seek(0, SeekOrigin.Begin); Shape shape = XamlReader.Load(stream) as Shape; AddShape(shape); } } } } private void AddShape(Shape shape) { Canvas.SetLeft(shape, left); Canvas.SetTop(shape, top); top += 20; left += 20; drawingCanvas.Children.Add(shape); undoStack.Push(shape); } private void RemoveShape(Shape shape) { top -= 20; left -= 20; Canvas.SetLeft(shape, left); Canvas.SetTop(shape, top); drawingCanvas.Children.Remove(shape); redoStack.Push(shape); } } }
copy paste with out undo redo
<Window x:Class="CopyAndPasteInCanvas.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="400" Width="600"> <Grid> <Canvas Name="drawingCanvas"/> </Grid> </Window>
namespace CopyAndPasteInCanvas { public partial class Window1 : Window { private Rectangle rect; private double top = 20; private double left = 20; public Window1() { InitializeComponent(); CommandBinding pasteCmdBinding = new CommandBinding(); pasteCmdBinding.Command = ApplicationCommands.Paste; pasteCmdBinding.Executed += pasteCmdBinding_Executed; pasteCmdBinding.CanExecute += pasteCmdBinding_CanExecute; this.CommandBindings.Add(pasteCmdBinding); CommandBinding copyCmdBinding = new CommandBinding(); copyCmdBinding.Command = ApplicationCommands.Copy; copyCmdBinding.Executed += copyCmdBinding_Executed; copyCmdBinding.CanExecute += copyCmdBinding_CanExecute; this.CommandBindings.Add(copyCmdBinding); rect = new Rectangle(); rect.Width = 60; rect.Height = 60; rect.Fill = Brushes.Red; } private void pasteCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = Clipboard.ContainsText(TextDataFormat.Xaml); } private void copyCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } private void copyCmdBinding_Executed(object sender, ExecutedRoutedEventArgs e) { string xaml = XamlWriter.Save(rect); Clipboard.SetText(xaml, TextDataFormat.Xaml); } private void pasteCmdBinding_Executed(object sender, ExecutedRoutedEventArgs e) { string xaml = Clipboard.GetText(TextDataFormat.Xaml); if (xaml != null) { using (MemoryStream stream = new MemoryStream(xaml.Length)) { using (StreamWriter sw = new StreamWriter(stream)) { sw.Write(xaml); sw.Flush(); stream.Seek(0, SeekOrigin.Begin); Shape shape = XamlReader.Load(stream) as Shape; Canvas.SetLeft(shape, left); Canvas.SetTop(shape, top); top += 20; left += 20; drawingCanvas.Children.Add(shape); } } } } } }
Automated Undo/Redo library based on C# Generics in .NET framework
http://www.codeproject.com/Articles/19550/Automated-Undo-Redo-library-Csharp-Generics-NET-C
收费控件
https://www.devexpress.com/Products/NET/Controls/WPF/Grid/
http://xceed.com/Index.aspx?Lang=EN-CA
免费UI设计工具
http://download.cnet.com/Indigo-Studio/3000-2247_4-75851417.html
ObservableCollection and CollectionChanged Event
http://stackoverflow.com/questions/3042179/observablecollection-and-collectionchanged-event
public class RangeObservableCollection<T> : ObservableCollection<T> { private bool surpressEvents = false; public void AddRange(IEnumerable<T> items) { surpressEvents = true; foreach (var item in items) { base.Add(item); } this.surpressEvents = false; this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, items.ToList())); } protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (!this.surpressEvents) { base.OnCollectionChanged(e); } } }
private RangeObservableCollection<InventoryBTO> _inventoryRecords; public RangeObservableCollection<InventoryBTO> InventoryRecords { get { return _inventoryRecords; } set { _inventoryRecords = value; } } private InventoryBTO _selectedRecord; public InventoryBTO SelectedRecord { get { return _selectedRecord; } set { if (_selectedRecord != value) { _selectedRecord = value; OnPropertyChanged(new PropertyChangedEventArgs("SelectedRecord")); } } } public InventoryViewModel() { if (_inventoryRecords == null) { InventoryRecords = new ObservableCollection<InventoryBTO>(); this.InventoryRecords.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryRecords_CollectionChanged); } this.InventoryRecords.AddRange(InventoryListBTO.GetAllInventoryRecords()); } void InventoryRecords_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { //e.NewItems will be an IList of all the items that were added in the AddRange method... }
To determine whether the ScrollBar is clicked or not
<Grid> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden" Name="myScrollViewer" PreviewMouseDown="myScrollViewer_PreviewMouseDown"> <StackPanel Name="imgStackPnl" Orientation="Horizontal"> <Image Source="1.jpg" Width="100" Margin="0,10"/> <Image Source="2.jpg" Width="100" Margin="0,10"/> <Image Source="3.jpg" Width="100"/> </StackPanel> </ScrollViewer> </Grid>
private void myScrollViewer_PreviewMouseDown(object sender, MouseButtonEventArgs e) { object original = e.OriginalSource; if (!original.GetType().Equals(typeof(ScrollViewer))) { if (original.GetType().Equals(typeof(Image))) { Console.WriteLine("image is clicked"); } else if (FindVisualParent<ScrollBar>(original as DependencyObject) != null) { Console.WriteLine("scroll bar is clicked"); } } } private parentItem FindVisualParent<parentItem>(DependencyObject obj) where parentItem:DependencyObject { DependencyObject parent = VisualTreeHelper.GetParent(obj); while (parent!=null && !parent.GetType().Equals(typeof(parentItem))) { parent = VisualTreeHelper.GetParent(parent); } return parent as parentItem; }
二叉树的例子
http://visualstudiogallery.msdn.microsoft.com/60297607-5fd4-4da4-97e1-3715e90c1a23/
Interaction design 交互式设计
https://en.wikipedia.org/wiki/Interaction_design
用户体验
http://baike.baidu.com/subview/274884/5077647.htm
交互设计师
http://baike.baidu.com/view/2316574.htm
用户体验设计
http://baike.baidu.com/view/1365273.htm
交互设计
http://baike.baidu.com/view/426920.htm
Copy Paste Image Example
https://files.cnblogs.com/files/CodingArt/WpfApplication1.zip
WPF: MultiBinding and IMultiValueConverter
http://blog.csainty.com/2009/12/wpf-multibinding-and.html
public class DataClass { public string FirstName { get; set; } public string Surname { get; set; } } public class NameMultiValueConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return String.Format("{0} {1}", values[0], values[1]); } } <Window xmlns:local="clr-namespace:BlogIMultiValueConverter"> <Window.Resources> <local:NameMultiValueConverter x:Key="NameMultiValueConverter" /> </Window.Resources> <Grid> <TextBox Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged}" /> <TextBox Text="{Binding Path=Surname, UpdateSourceTrigger=PropertyChanged}" /> <TextBlock> <TextBlock.Text> <MultiBinding Converter="{StaticResource MultiValueConverter}"> <Binding Path="FirstName" /> <Binding Path="Surname" /> </MultiBinding> </TextBlock.Text> </TextBlock> </Grid> </Window>
Combobox 下拉框 是 datagrid
http://www.nullskull.com/a/1428/wpf-datagrid-as-combobox-dropdown-part-2.aspx
http://www.codeproject.com/Articles/43074/WPF-Custom-ComboBox
Material Design in XAML Toolkit
DataGrid
下面代码中,按下tab键后,焦点从txt1,直接跳转到txt2:
<Windows.Resources> <Style x:Key="cellstyle" TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MetroDataGridCell}"> <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/> </Style> </Windows.Resources> <DataGrid CellStyle="{StaticResource cellstyle}"> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox x:Name="txt1"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox x:Name="txt1"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
https://social.msdn.microsoft.com/Forums/en-US/5f17c332-673c-43ed-a818-67bd9429400d/wpf-datagrid-datagridtemplatecolumn-tab-focus-issue?forum=wpf
To be continued...