- 浏览: 399677 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (309)
- xaml C# wpf (0)
- scala java inner clas (1)
- Tools UML Eclipse UML2 (1)
- Timer .NET Framework (1)
- perl (6)
- python function paramter (1)
- Python Docstring (1)
- Python how to compare types (1)
- Python (8)
- java (5)
- C# (76)
- C# WPF (0)
- p4 (0)
- WPF (46)
- .net (6)
- xaml (1)
- javascript (40)
- windows (10)
- scala (4)
- winform (1)
- c++ (48)
- tools (12)
- cmd (1)
- os (0)
- CI (0)
- shell (0)
- C (2)
- haskell (49)
- functional (1)
- tool (1)
- gnu (1)
- linux (1)
- kaskell (0)
- svn (0)
- wcf (3)
- android (1)
最新评论
Reprint - Code implementation - Use The List View
This is the implementation code with annotation that helps to illustrate the triplet of "Using the List View" from "Part I" to "Part III".
WPF Tutorial - Using ListView, Part I
WPF Tutorial - Using ListView, Part II
WPF Tutorial - Using ListView, Part III
The topic cover from the basic of ListView capability to more advanced and more customized ones such as define the Sorting and Inline editing of ListViews.
There is a lots of code, which I would recommend that you read along their orginal blogs. Below is the code with my own connotation in the code.
ListView basic
Below is the code that demonstrate the basic use of ListViews.
xaml part.
<!-- you can either set the DataContext to itself, with the following code --> <!--<Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" >--> <!-- or you give a name to yourself, in this case, the name is "This" later, you can bind to "This"--> <Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:ListView1" Title="MainWindow" Height="350" Width="525" x:Name="This" > <StackPanel> <ListView> <ListView.View> <!-- For ListView, to have it to show as the Grid based view, the key is to Listview.View and you will need to nest the GridView into the ListView.View --> <GridView> <GridViewColumn Width="140" Header="1" /> <GridViewColumn Width="140" Header="2" /> <GridViewColumn Width="140" Header="3" /> </GridView> </ListView.View> </ListView> <!-- below shows how bind different column to the data field (DisplayMember) --> <ListView> <ListView.View> <GridView> <!-- data to this column won't need a DisplayMember attribute because if it is omitted, then it is the whole data that get displayed --> <GridViewColumn Width="120" Header="Date" /> <GridViewColumn Width="120" Header="Day of Week" DisplayMemberBinding="{Binding DayOfWeek}" /> <GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" /> </GridView> </ListView.View> <sys:DateTime>1/2/3</sys:DateTime> <sys:DateTime>4/5/6</sys:DateTime> <sys:DateTime>7/8/9</sys:DateTime> <sys:DateTime>10/11/12</sys:DateTime> </ListView> <!-- this is yet another example, which shows how to bind to data and etc... SO far so good, let dive into how to sort ListView and etc.. --> <!-- this is when you have datacontex set to itself --> <!--<ListView x:Name="gameListView" ItemsSource="{Binding Path=GameCollection}" >--> <!-- This is when you have already assigned a name to the top level control (The window control) --> <ListView x:Name="gameListView" ItemsSource="{Binding ElementName=This, Path=GameCollection}" > <ListView.View> <GridView> <GridViewColumn Width="140" Header="Game Name" DisplayMemberBinding="{Binding GameName}" /> <GridViewColumn Width="140" Header="Creator" DisplayMemberBinding="{Binding Creator}" /> <GridViewColumn Width="140" Header="Publisher" DisplayMemberBinding="{Binding Publisher}" /> </GridView> </ListView.View> </ListView> <Button HorizontalAlignment="Right" Margin="5,5,5,5" Content="Add Row" Click="AddRow_Click" /> </StackPanel> </Window>
the C# parts.
namespace ListView1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeMainWindow(); } #region Data public class GameData { public string GameName { get; set; } public string Creator { get; set; } public string Publisher { get;set; } } ObservableCollection<GameData> _GameCollection = new ObservableCollection<GameData>(); public void InitializeMainWindow() { // This will initialize a load of data into the _GameCollection _GameCollection.Add(new GameData { GameName = "World Of Warcraft", Creator = "Blizzard", Publisher = "Blizzard" }); _GameCollection.Add(new GameData { GameName = "Halo", Creator = "Bungie", Publisher = "Microsoft" }); _GameCollection.Add(new GameData { GameName = "Gears of War", Creator = "Epic", Publisher = "Microsoft" }); } // expose the ObservableCollection as Property that you can bind to public ObservableCollection<GameData> GameCollection { get { return _GameCollection; } } #endregion Data } }
ListView Sorting
Below show the code that has implement the sorting within ListView.
the .xaml parts
<!-- you can either set the DataContext to itself, with the following code --> <!--<Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" >--> <!-- or you give a name to yourself, in this case, the name is "This" later, you can bind to "This"--> <Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:ListView1" Title="MainWindow" Height="350" Width="525" x:Name="This" > <StackPanel> <!-- while the abovce code is a non-sortable version, below will utilize the sorting function --> <!-- ... Omiss of the irrelevant part --><Button HorizontalAlignment="Right" Margin="5,5,5,5" Content="Add Row" Click="AddRow_Click" /> <ListView x:Name="gameListView2" ItemsSource="{Binding ElementName=This, Path=GameCollection}" > <ListView.View> <GridView> <GridViewColumn Width="140" DisplayMemberBinding="{Binding GameName}"> <!-- in this example, the Tag property holds some data, the data being the name of backing field that we want to sort on --> <GridViewColumnHeader Click="SortClick" Tag="GameName" Content="Game Name"> </GridViewColumnHeader> </GridViewColumn> <GridViewColumn Width="140" DisplayMemberBinding="{Binding Creator}"> <GridViewColumnHeader Click="SortClick" Tag="Creator" Content="Creator"> </GridViewColumnHeader> </GridViewColumn> <GridViewColumn Width="140" DisplayMemberBinding="{Binding Publisher}"> <GridViewColumnHeader Click="SortClick" Tag="Publisher" Content="Publisher"> </GridViewColumnHeader> </GridViewColumn> </GridView> </ListView.View> </ListView> </StackPanel> </Window>
And the C# code part.
namespace ListView1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeMainWindow(); } #region Sorting private GridViewColumnHeader _CurSortCol = null; private SortAdorner _CurAdorner = null; // Can we apply the style on the ListView, is the Adorner layer the only option? // private void SortClick(object sender, RoutedEventArgs e) { GridViewColumnHeader column = sender as GridViewColumnHeader; String field = column.Tag as string; // now SortClick only works with the gameListVIew2, // you can leverage the VisualTreeHelper to look for // the LiveView. // below show the code to find the parent var parent = column.Parent; while (parent != null) { if (parent is ListView) { break; } parent = VisualTreeHelper.GetParent(parent); } if (_CurSortCol != null) { // if the current column is not null, we remove the previous adorner AdornerLayer.GetAdornerLayer(_CurSortCol).Remove(_CurAdorner); //gameListView2.Items.SortDescriptions.Clear(); ((ListView)parent).Items.SortDescriptions.Clear(); } ListSortDirection newDir = ListSortDirection.Ascending; if (_CurSortCol == column && _CurAdorner.Direction == newDir) newDir = ListSortDirection.Descending; _CurSortCol = column; _CurAdorner = new SortAdorner(_CurSortCol, newDir); AdornerLayer.GetAdornerLayer(_CurSortCol).Add(_CurAdorner); //gameListView2.Items.SortDescriptions.Add(new SortDescription(field, newDir)); ((ListView)parent).Items.SortDescriptions.Add(new SortDescription(field, newDir)); } // you may take reference to the http://www.switchonthecode.com/tutorials/wpf-tutorial-using-the-listview-part-2-sorting // for more illustration on the Adorners public class SortAdorner : Adorner { private readonly static Geometry _AscGeometry = Geometry.Parse("M 0,0 L 10,0 L 5,5 Z"); private readonly static Geometry _DescGeometry = Geometry.Parse("M 0,5 L 10,5 L 5,0 Z"); // keep record of the current sorting direction public ListSortDirection Direction { get; private set; } public SortAdorner(UIElement element, ListSortDirection dir) : base(element) { Direction = dir; } // the significant part of the adorner is the OnRender method, // you will need to add the triangle to indica the direction of the sorting protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); // do nothing if decorated element is less than 20 in width if (AdornedElement.RenderSize.Width < 20) return; // why we need to apply the Transformation with the Push and Pop method ?? // is that because we can push something while the transform still affect others down // in the stream? drawingContext.PushTransform( new TranslateTransform( AdornedElement.RenderSize.Width - 15, (AdornedElement.RenderSize.Height - 5) / 2)); drawingContext.DrawGeometry( Brushes.Black, null, Direction == ListSortDirection.Ascending ? _AscGeometry : _DescGeometry); drawingContext.Pop(); } } private void AddRow_Click(object sender, RoutedEventArgs e) { _GameCollection.Add(new GameData { GameName = "A New Game", Creator = "A New Creator", Publisher = "A New Publisher" } ); } #endregion Sorting } }
ListView Inline Edit
The xaml part of the code
<!-- you can either set the DataContext to itself, with the following code --> <!--<Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" >--> <!-- or you give a name to yourself, in this case, the name is "This" later, you can bind to "This"--> <Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:ListView1" Title="MainWindow" Height="350" Width="525" x:Name="This" > <StackPanel> <ListView x:Name="editableGameListView2" ItemsSource="{Binding ElementName=This, Path=BindableGameCollection}" > <!-- Define Resource that shall be used --> <ListView.Resources> <!-- Here you have to define the Customer Converter --> <local:BoolToVisibilityConverter x:Key="boolToVis" /> <Style TargetType="{x:Type TextBlock}" x:Key="GridBlockStyle" > <Setter Property="VerticalAlignment" Value="Center" /> <!-- the TextBlock or the TextBox within are both embedded inside the ListViewItem element --> <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource boolToVis},ConverterParameter=false}" /> </Style> <!-- You may wonder why we don't put the TargetType of GridEditStyle? The reason is because we are going to apply the GridEditStyle on both the TextBox and the ComboBox So we have to choose the common base (denominator), here in this case, their common case are FrameElement So it demonstrate that you can create some base types and applies to the child Element. --> <Style TargetType="{x:Type FrameworkElement}" x:Key="GridEditStyle"> <Setter Property="VerticalAlignment" Value="Center"></Setter> <!-- there is a converter parameter, which will invert the Visibility of Boolean2Visibility --> <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource boolToVis}, ConverterParameter=true}"></Setter> </Style> </ListView.Resources> <!-- define the view of the ListView--> <ListView.View> <GridView> <GridViewColumn Width="140"> <GridViewColumnHeader Click="SortClick" Tag="GameName" Content="Game Name" /> <GridViewColumn.CellTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding Path=GameName}" Style="{StaticResource GridBlockStyle}" /> <TextBox Text="{Binding Path=GameName}" Style="{StaticResource GridEditStyle}" /> </Grid> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Width="140"> <GridViewColumnHeader Click="SortClick" Tag="Creator" Content="Creator" /> <GridViewColumn.CellTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding Path=Creator}" Style="{StaticResource GridBlockStyle}" /> <TextBox Text="{Binding Path=Creator}" Style="{StaticResource GridEditStyle}" /> </Grid> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Width="140"> <GridViewColumnHeader Click="SortClick" Tag="Publisher" Content="Publisher" /> <GridViewColumn.CellTemplate> <DataTemplate> <!-- why we want to have the Grid's View style to be Strech?? --> <Grid HorizontalAlignment="Stretch" > <!-- While for the Publisher, we will use a ComboBox to let you choose the right publisher --> <TextBlock Text="{Binding Path=Publisher}" Style="{StaticResource GridBlockStyle}" /> <ComboBox Text="{Binding Path=Publisher}" Style="{StaticResource GridEditStyle}" ItemsSource="{Binding ElementName=This, Path=AvailablePublishers}" /> </Grid> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView> <Button Content="Add Row" Click="AddBindableRowClick" HorizontalAlignment="Right" Margin="5" /> </StackPanel> </Window>
And the C# parts.
namespace ListView1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeMainWindow(); InitializeBindableGameData(); } #region Inline Editing // Comparing ot the GameData which is a plain data object // the BindableGameData is a class that you can bind to UI // it // But, however, why do we need to make the BindableGameData // a subsclass of the DependencyObject? // // QUESTION: // you may want to find out the difference between using the DependencyObject and the INotifyPropertyChanged interface // // https://channel9.msdn.com/Forums/TechOff/466194-ViewModel--INotifyPropertyChanged-or-DependencyObject // http://blog.quantumbitdesigns.com/2010/01/26/mvvm-lambda-vs-inotifypropertychanged-vs-dependencyobject/ public class BindableGameData : DependencyObject { public string GameName { get { return (string)GetValue(GameNameProperty); } set { SetValue(GameNameProperty, value); } } // Using a DependencyProperty as the backing store for GameName. This enables animation, styling, binding, etc... public static readonly DependencyProperty GameNameProperty = DependencyProperty.Register("GameName", typeof(string), typeof(BindableGameData), new UIPropertyMetadata(null)); public string Creator { get { return (string)GetValue(CreatorProperty); } set { SetValue(CreatorProperty, value); } } // Using a DependencyProperty as the backing store for Creator. This enables animation, styling, binding, etc... public static readonly DependencyProperty CreatorProperty = DependencyProperty.Register("Creator", typeof(string), typeof(BindableGameData), new UIPropertyMetadata(null)); public string Publisher { get { return (string)GetValue(PublisherProperty); } set { SetValue(PublisherProperty, value); } } // Using a DependencyProperty as the backing store for Publisher. This enables animation, styling, binding, etc... public static readonly DependencyProperty PublisherProperty = DependencyProperty.Register("Publisher", typeof(string), typeof(BindableGameData), new UIPropertyMetadata(null)); } private void AddBindableRowClick(object sender, RoutedEventArgs e) { _BindableGameCollection.Add(new BindableGameData { GameName = "A New Game", Creator = "A New Creator", Publisher = "<Select A Publisher", } ); } private ObservableCollection<BindableGameData> _BindableGameCollection = new ObservableCollection<BindableGameData>(); private ObservableCollection<string> _AvailablePublishers = new ObservableCollection<string>(); public ObservableCollection<BindableGameData> BindableGameCollection { get { return _BindableGameCollection; } } public ObservableCollection<string> AvailablePublishers { get { return _AvailablePublishers; } } private void InitializeBindableGameData() { _BindableGameCollection.Add(new BindableGameData { GameName = "World Of Warcraft", Creator = "Blizzard", Publisher = "Blizzard" }); _BindableGameCollection.Add(new BindableGameData { GameName = "Halo", Creator = "Bungie", Publisher = "Microsoft" }); _BindableGameCollection.Add(new BindableGameData { GameName = "Gears Of War", Creator = "Epic", Publisher = "Microsoft" }); _AvailablePublishers.Add("Microsoft"); _AvailablePublishers.Add("Blizzard"); _AvailablePublishers.Add("Nintendo"); _AvailablePublishers.Add("Electronic Arts"); _AvailablePublishers.Add("Activision"); _AvailablePublishers.Add("Ubisoft"); _AvailablePublishers.Add("Take-Two Interactive"); } #endregion Inline Editing } #region Inline Editing Converter(s) public class BoolToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var val = (bool)value; var param = bool.Parse(parameter as string); return val == param ? Visibility.Visible : Visibility.Hidden; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } #endregion Inline Editing Converter(s) }
相关推荐
本资源"reprint-0.3.0.tar.gz"就是从PyPI官网获取的一个Python库——`reprint`的特定版本,版本号为0.3.0。 `reprint`库主要解决的是在Python程序中动态更新控制台输出的问题。在开发过程中,我们有时需要实时显示...
Gartner在2018年发布的研究笔记中,特别提到了应用安全测试(AST)市场的现状和发展趋势。研究笔记的标题为“应用安全测试市场的魔法象限”,它由分析师Ayal Tirosh、Dionisio Zumerle和Mark Horvath撰写,涉及...
Eliminates the need to deal with the different available Fingerprint APIs, including Imprint and Samsung Pass. Fixes undocumented bugs and idiosyncrasies in the underlying APIs. Supports more Imprint ...
Processing of signals is often facilitated by transforming to a representation in ...natural coordinate system, the components of the signal may be manip-ulated, transmitted, or stored more efficiently.
reprint 是一个适用于 Python 2/3 的简易变量绑定与多行输出刷新的库
reprint 使用说明 直接从datasource,dbgrid,stringgrid导入数据, 只需简单设置,不用手工制作,即可生成您需要的报表,具有预览功能。即可自定义纸张,又可适应 打印机默认纸张。各种打印设置,功能更强大。 ...
ity of all materials or the consequences of their use. The authors and publishers have attempted to trace the copyright holders of all material reproduced in this publication and apologize to ...
output_type : "list"或"dict" (默认值: "list" ),指示列表模式或dict模式。 initial_len : int (默认值: 1 ),仅在列表模式下工作,指示列表的初始长度。 它用于按索引修改内容,而无需初始化。 inte
reprint 使用说明 本人长期使用delphi做数据库的开发,报表控件使用Quickrpt,在打印上经常遇到一些问题,于是自己经常编写一部分打印的程序,经过总结开发了这个控件。 本控件可打印 datasource,dbgrid,...
In view of the new evidence and of the great interest which the Hartogs and CR extension phenomena have generated over many decades, I have completely revised and expanded the relevant sectionsof ...
是检测估计和调制理论的经典著作,最新版,2013版,英文原版,Highly readable paperback reprint of one of the great time-tested classics in the field of signal processing Together with the reprint of Part ...
of all materials or the consequences of their use. The authors and publishers have attempted to trace the copyright holders of all material reproduced in this publication and apologize to copyright ...
不推荐使用请改用 ,它支持... 在您的Application.onCreate ,使用Reprint.initialize(this)初始化Reprint。 这将加载棉花糖模块和Spass模块(如果包含)。 然后,在代码中的任何位置,都可以调用Reprint.authenticate
cannot assume responsibility for the validity of all materials or the consequences of their use. The Authors and Publishers have attempted to trace the copyright holders of all material reproduced in ...
Reasonable efforts have been made to publish reliable data and information, but the author and publisher cannot assume responsibility for the validity of all materials or the consequences of their use....