Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4589 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
12 changed files with 603 additions and 93 deletions
@ -0,0 +1,176 @@ |
|||||||
|
<UserControl x:Class="ICSharpCode.SharpDevelop.Debugging.DebuggerTooltipControl" |
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||||
|
<UserControl.Resources> |
||||||
|
<!-- TODO move styles to ResourceDictionary --> |
||||||
|
<Style x:Key="ExpandCollapseToggleStyle" |
||||||
|
TargetType="{x:Type ToggleButton}"> |
||||||
|
<Setter Property="Focusable" |
||||||
|
Value="False"/> |
||||||
|
<Setter Property="Width" |
||||||
|
Value="19"/> |
||||||
|
<Setter Property="Height" |
||||||
|
Value="13"/> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type ToggleButton}"> |
||||||
|
<Border Width="19" |
||||||
|
Height="13" |
||||||
|
Background="Transparent"> |
||||||
|
<Border Width="9" |
||||||
|
Height="9" |
||||||
|
BorderThickness="1" |
||||||
|
BorderBrush="#FF7898B5" |
||||||
|
CornerRadius="1" |
||||||
|
SnapsToDevicePixels="true"> |
||||||
|
<Border.Background> |
||||||
|
<LinearGradientBrush StartPoint="0,0" |
||||||
|
EndPoint="1,1"> |
||||||
|
<LinearGradientBrush.GradientStops> |
||||||
|
<GradientStop Color="White" |
||||||
|
Offset=".2"/> |
||||||
|
<GradientStop Color="#FFC0B7A6" |
||||||
|
Offset="1"/> |
||||||
|
</LinearGradientBrush.GradientStops> |
||||||
|
</LinearGradientBrush> |
||||||
|
</Border.Background> |
||||||
|
<Path x:Name="ExpandPath" |
||||||
|
Margin="1,1,1,1" |
||||||
|
Fill="Black" |
||||||
|
Data="M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z"/> |
||||||
|
</Border> |
||||||
|
</Border> |
||||||
|
<ControlTemplate.Triggers> |
||||||
|
<Trigger Property="IsChecked" |
||||||
|
Value="True"> |
||||||
|
<Setter Property="Data" |
||||||
|
TargetName="ExpandPath" |
||||||
|
Value="M 0 2 L 0 3 L 5 3 L 5 2 Z"/> |
||||||
|
</Trigger> |
||||||
|
</ControlTemplate.Triggers> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
<Style x:Key="upDownBorderStyle" TargetType="{x:Type Border}"> |
||||||
|
<Setter Property="BorderBrush" Value="Gray" /> |
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" /> |
||||||
|
<Setter Property="Margin" Value="0" /> |
||||||
|
<Setter Property="Background" Value="#FFECF7FC" /> |
||||||
|
<Style.Triggers> |
||||||
|
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="False"> |
||||||
|
<Setter Property="Background" Value="#FFE0E0E0"></Setter> |
||||||
|
</DataTrigger> |
||||||
|
</Style.Triggers> |
||||||
|
</Style> |
||||||
|
<Style x:Key="upButtonStyle" TargetType="{x:Type RepeatButton}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type RepeatButton}"> |
||||||
|
<Border Style="{StaticResource upDownBorderStyle}" BorderThickness="1 1 1 0"> |
||||||
|
<ContentPresenter HorizontalAlignment="Center"></ContentPresenter> |
||||||
|
</Border> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
<Style x:Key="downButtonStyle" TargetType="{x:Type RepeatButton}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type RepeatButton}"> |
||||||
|
<Border Style="{StaticResource upDownBorderStyle}" BorderThickness="1 0 1 1"> |
||||||
|
<ContentPresenter HorizontalAlignment="Center"></ContentPresenter> |
||||||
|
</Border> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
</UserControl.Resources> |
||||||
|
<StackPanel Orientation="Vertical"> |
||||||
|
<RepeatButton Name="btnUp" Style="{StaticResource upButtonStyle}" Content="^" Click="BtnUp_Click"></RepeatButton> |
||||||
|
<DataGrid VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" |
||||||
|
GridLinesVisibility="None" |
||||||
|
RowHeight="20" MaxHeight="202" |
||||||
|
SelectionMode="Single" |
||||||
|
SelectionUnit="FullRow" |
||||||
|
ItemsSource="{Binding}" |
||||||
|
Name="dataGrid" |
||||||
|
AutoGenerateColumns="False" |
||||||
|
CanUserAddRows="False" HeadersVisibility="None" |
||||||
|
BorderBrush="Gray" |
||||||
|
BorderThickness="1"> |
||||||
|
<DataGrid.Background> |
||||||
|
<LinearGradientBrush StartPoint="0,-0.03" EndPoint="0,1"> |
||||||
|
<GradientStop Color="White"/> |
||||||
|
<GradientStop Color="#FFFAFCFE" Offset="0.983"/> |
||||||
|
<GradientStop Color="#FFECF7FC" Offset="0.07"/> |
||||||
|
<GradientStop Color="#FFEEF7FA" Offset="0.436"/> |
||||||
|
</LinearGradientBrush> |
||||||
|
</DataGrid.Background> |
||||||
|
<DataGrid.RowStyle> |
||||||
|
<Style TargetType="{x:Type DataGridRow}"> |
||||||
|
<Setter Property="Background" Value="Transparent"></Setter> |
||||||
|
<Style.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter Property="Background" Value="#FFE2F6FE" /> |
||||||
|
</Trigger> |
||||||
|
</Style.Triggers> |
||||||
|
</Style> |
||||||
|
</DataGrid.RowStyle> |
||||||
|
<DataGrid.CellStyle> |
||||||
|
<Style TargetType="{x:Type DataGridCell}"> |
||||||
|
<Setter Property="Focusable" Value="false" /> |
||||||
|
<Setter Property="BorderThickness" Value="0" /> |
||||||
|
</Style> |
||||||
|
</DataGrid.CellStyle> |
||||||
|
<DataGrid.Columns> |
||||||
|
<DataGridTemplateColumn> <!-- "Plus" expander --> |
||||||
|
<DataGridTemplateColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<Grid Background="White"> |
||||||
|
<StackPanel VerticalAlignment="Center"> |
||||||
|
<ToggleButton x:Name="PropertyExpander" Style="{StaticResource ExpandCollapseToggleStyle}" Click="Expander_Click" Padding="0" Margin="0 0 0 0" /> |
||||||
|
</StackPanel> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<DataTrigger Binding="{Binding Path=ShowPropertyButton}" Value="False"> |
||||||
|
<Setter TargetName="PropertyExpander" |
||||||
|
Property="Visibility" Value="Hidden"/> |
||||||
|
</DataTrigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
</DataGridTemplateColumn.CellTemplate> |
||||||
|
</DataGridTemplateColumn> |
||||||
|
<!-- Icon |
||||||
|
<DataGridTemplateColumn> |
||||||
|
<DataGridTemplateColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
</DataTemplate> |
||||||
|
</DataGridTemplateColumn.CellTemplate> |
||||||
|
</DataGridTemplateColumn> --> |
||||||
|
<DataGridTemplateColumn MinWidth="20" Header="Name"> <!-- Name --> |
||||||
|
<DataGridTemplateColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<Border BorderBrush="#FFDDDDDD" BorderThickness="0 0 1 0"> |
||||||
|
<TextBlock Margin="0 0 6 0" Text="{Binding Path=Name, Mode=OneWay}"></TextBlock> |
||||||
|
</Border> |
||||||
|
</DataTemplate> |
||||||
|
</DataGridTemplateColumn.CellTemplate> |
||||||
|
</DataGridTemplateColumn> |
||||||
|
<!-- Visualizer picker |
||||||
|
<DataGridTemplateColumn> |
||||||
|
<DataGridTemplateColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
</DataTemplate> |
||||||
|
</DataGridTemplateColumn.CellTemplate> |
||||||
|
</DataGridTemplateColumn> --> |
||||||
|
<!-- Value --> |
||||||
|
<DataGridTextColumn MinWidth="20" |
||||||
|
Header="Value" Width="Auto" |
||||||
|
Binding="{Binding Path=Value, Mode=OneWay}"/> |
||||||
|
</DataGrid.Columns> |
||||||
|
</DataGrid> |
||||||
|
<RepeatButton Name="btnDown" Style="{StaticResource downButtonStyle}" Content="v" Click="BtnDown_Click"></RepeatButton> |
||||||
|
</StackPanel> |
||||||
|
</UserControl> |
||||||
@ -0,0 +1,103 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Controls.Primitives; |
||||||
|
using System.Windows.Data; |
||||||
|
using System.Windows.Documents; |
||||||
|
using System.Windows.Input; |
||||||
|
using System.Windows.Media; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Debugging |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Default Control used as content of SharpDevelop debugger tooltips.
|
||||||
|
/// </summary>
|
||||||
|
public partial class DebuggerTooltipControl : UserControl, ITooltip |
||||||
|
{ |
||||||
|
public DebuggerTooltipControl() |
||||||
|
{ |
||||||
|
InitializeComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
private LazyItemsControl<ITreeNode> lazyGrid; |
||||||
|
|
||||||
|
private IEnumerable<ITreeNode> itemsSource; |
||||||
|
public IEnumerable<ITreeNode> ItemsSource |
||||||
|
{ |
||||||
|
set |
||||||
|
{ |
||||||
|
this.itemsSource = value; |
||||||
|
this.lazyGrid = new LazyItemsControl<ITreeNode>(this.dataGrid, 12); |
||||||
|
lazyGrid.ItemsSource = new VirtualizingIEnumerable<ITreeNode>(value); |
||||||
|
this.dataGrid.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(handleScroll)); |
||||||
|
|
||||||
|
if (this.lazyGrid.ItemsSourceTotalCount != null) |
||||||
|
{ |
||||||
|
btnUp.Visibility = btnDown.Visibility = |
||||||
|
this.lazyGrid.ItemsSourceTotalCount.Value <= 10 ? Visibility.Collapsed : Visibility.Visible; |
||||||
|
} |
||||||
|
} |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.itemsSource; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether DebuggerTooltipControl should be displayed in WPF Popup.
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowAsPopup { |
||||||
|
get { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the debugger Popup containing this control. Also closes all child Popups.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool Close() |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
|
||||||
|
private void Expander_Click(object sender, RoutedEventArgs e) |
||||||
|
{ |
||||||
|
var clickedButton = (ToggleButton)e.OriginalSource; |
||||||
|
Point buttonPos = clickedButton.PointToScreen(new Point(0, 0)); |
||||||
|
|
||||||
|
if (clickedButton.IsChecked.GetValueOrDefault(false)) |
||||||
|
{ |
||||||
|
// open child Popup
|
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// close child Popups
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void handleScroll(object sender, ScrollChangedEventArgs e) |
||||||
|
{ |
||||||
|
btnUp.IsEnabled = !this.lazyGrid.IsScrolledToStart; |
||||||
|
btnDown.IsEnabled = !this.lazyGrid.IsScrolledToEnd; |
||||||
|
} |
||||||
|
|
||||||
|
void BtnUp_Click(object sender, RoutedEventArgs e) |
||||||
|
{ |
||||||
|
this.lazyGrid.ScrollViewer.ScrollUp(1); |
||||||
|
} |
||||||
|
|
||||||
|
void BtnDown_Click(object sender, RoutedEventArgs e) |
||||||
|
{ |
||||||
|
this.lazyGrid.ScrollViewer.ScrollDown(1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Debugging |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Content of debugger tooltip, specifying whether it should be displayed in a WPF Popup.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITooltip |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// If true, this ITooltip will be displayed in a WPF Popup.
|
||||||
|
/// Otherwise this will be displayed in a WPF Tooltip.
|
||||||
|
/// WPF Popups are (unlike WPF Tooltips) focusable.
|
||||||
|
/// </summary>
|
||||||
|
bool ShowAsPopup { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes this debugger tooltip.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if Close succeeded, false otherwise.</returns>
|
||||||
|
bool Close(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Debugging |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Node that can be bound to DebuggerTooltipControl.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITreeNode |
||||||
|
{ |
||||||
|
string Name { get; } |
||||||
|
|
||||||
|
string Text { get; } |
||||||
|
|
||||||
|
string Type { get; } |
||||||
|
|
||||||
|
IEnumerable<ITreeNode> ChildNodes { get; } |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,120 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Windows.Controls; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Debugging |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// ItemsControl wrapper that takes VirtualizingIEnumerable as source,
|
||||||
|
/// and adds additional items from the source to underlying ItemsControl when scrolled to bottom.
|
||||||
|
/// </summary>
|
||||||
|
public class LazyItemsControl<T> |
||||||
|
{ |
||||||
|
private ItemsControl itemsControl; |
||||||
|
private int initialItemsCount; |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new instance of LazyItemsControl.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wrappedItemsControl">ItemsControl to wrap and add items to it when scrolled to bottom.</param>
|
||||||
|
/// <param name="initialItemsCount">Number of items to be initially displayed in wrapped ItemsControl.</param>
|
||||||
|
public LazyItemsControl(ItemsControl wrappedItemsControl, int initialItemsCount) |
||||||
|
{ |
||||||
|
if (wrappedItemsControl == null) |
||||||
|
throw new ArgumentNullException("wrappedItemsControl"); |
||||||
|
|
||||||
|
this.initialItemsCount = initialItemsCount; |
||||||
|
this.itemsControl = wrappedItemsControl; |
||||||
|
this.itemsControl.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(handleScroll)); |
||||||
|
} |
||||||
|
|
||||||
|
private ScrollViewer scrollViewerCached; |
||||||
|
public ScrollViewer ScrollViewer |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (this.scrollViewerCached == null) |
||||||
|
this.scrollViewerCached = this.itemsControl.GetScrollViewer(); |
||||||
|
return this.scrollViewerCached; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsScrolledToStart |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (ScrollViewer == null) // Visual tree not initialized yet
|
||||||
|
return false; |
||||||
|
return ScrollViewer.VerticalOffset == 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsScrolledToEnd |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (itemsSourceTotalCount == null) { |
||||||
|
// not scrolled to end of IEnumerable yet
|
||||||
|
return false; |
||||||
|
} |
||||||
|
// already scrolled to end of IEnumerable
|
||||||
|
int totalItems = itemsSourceTotalCount.Value; |
||||||
|
return (ScrollViewer.VerticalOffset >= totalItems - ScrollViewer.ViewportHeight); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int? itemsSourceTotalCount = null; |
||||||
|
/// <summary> Items count of underlying IEnumerable. Null until scrolled to the end of IEnumerable. </summary>
|
||||||
|
public int? ItemsSourceTotalCount |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.itemsSourceTotalCount; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private VirtualizingIEnumerable<T> itemsSource; |
||||||
|
/// <summary> The collection that underlying ItemsControl sees. </summary>
|
||||||
|
public VirtualizingIEnumerable<T> ItemsSource |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return itemsSource; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
this.itemsSource = value; |
||||||
|
addNextItems(this.itemsSource, initialItemsCount); |
||||||
|
this.itemsControl.ItemsSource = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void addNextItems(VirtualizingIEnumerable<T> sourceToAdd, int nItems) |
||||||
|
{ |
||||||
|
sourceToAdd.AddNextItems(nItems); |
||||||
|
if (!sourceToAdd.HasNext) |
||||||
|
{ |
||||||
|
// all items from IEnumerable have been added
|
||||||
|
this.itemsSourceTotalCount = sourceToAdd.Count; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void handleScroll(object sender, ScrollChangedEventArgs e) |
||||||
|
{ |
||||||
|
if (e.VerticalChange > 0) |
||||||
|
{ |
||||||
|
// scrolled to bottom
|
||||||
|
if (e.VerticalOffset >= this.itemsSource.Count - e.ViewportHeight) |
||||||
|
{ |
||||||
|
addNextItems(this.itemsSource, (int)e.VerticalChange); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Debugging |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// A wrapper around IEnumerable<T> with AddNextItems method for pulling additional items
|
||||||
|
/// from underlying IEnumerable<T>.
|
||||||
|
/// Can be used as source for <see cref="LazyItemsControl" />.
|
||||||
|
/// </summary>
|
||||||
|
public class VirtualizingIEnumerable<T> : ObservableCollection<T> |
||||||
|
{ |
||||||
|
private IEnumerator<T> originalSourceEnumerator; |
||||||
|
|
||||||
|
public VirtualizingIEnumerable(IEnumerable<T> originalSource) |
||||||
|
{ |
||||||
|
if (originalSource == null) |
||||||
|
throw new ArgumentNullException("originalSource"); |
||||||
|
|
||||||
|
this.originalSourceEnumerator = originalSource.GetEnumerator(); |
||||||
|
} |
||||||
|
|
||||||
|
private bool hasNext = true; |
||||||
|
/// <summary>
|
||||||
|
/// False if all items from underlying IEnumerable have already been added.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasNext |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.hasNext; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requests next <paramref name="count"/> items from underlying IEnumerable source and adds them to the collection.
|
||||||
|
/// </summary>
|
||||||
|
public void AddNextItems(int count) |
||||||
|
{ |
||||||
|
for (int i = 0; i < count; i++) |
||||||
|
{ |
||||||
|
if (!originalSourceEnumerator.MoveNext()) |
||||||
|
{ |
||||||
|
this.hasNext = false; |
||||||
|
break; |
||||||
|
} |
||||||
|
this.Add(originalSourceEnumerator.Current); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Koníèek" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Media; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Scrolling related helpers.
|
||||||
|
/// </summary>
|
||||||
|
public static class ScrollUtils |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Searches VisualTree of given object for a ScrollViewer.
|
||||||
|
/// </summary>
|
||||||
|
public static ScrollViewer GetScrollViewer(this DependencyObject o) |
||||||
|
{ |
||||||
|
var scrollViewer = o as ScrollViewer; |
||||||
|
if (scrollViewer != null) { |
||||||
|
return scrollViewer; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++) |
||||||
|
{ |
||||||
|
var child = VisualTreeHelper.GetChild(o, i); |
||||||
|
var result = GetScrollViewer(child); |
||||||
|
if (result != null) { |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scrolls ScrollViewer up by given offset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Offset by which to scroll up. Should be positive.</param>
|
||||||
|
public static void ScrollUp(this ScrollViewer scrollViewer, double offset) |
||||||
|
{ |
||||||
|
ScrollUtils.ScrollByVerticalOffset(scrollViewer, -offset); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scrolls ScrollViewer down by given offset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Offset by which to scroll down. Should be positive.</param>
|
||||||
|
public static void ScrollDown(this ScrollViewer scrollViewer, double offset) |
||||||
|
{ |
||||||
|
ScrollUtils.ScrollByVerticalOffset(scrollViewer, offset); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scrolls ScrollViewer by given vertical offset.
|
||||||
|
/// </summary>
|
||||||
|
public static void ScrollByVerticalOffset(this ScrollViewer scrollViewer, double offset) |
||||||
|
{ |
||||||
|
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue