Hidden expander overlap below it - c#

I have little problem.
In my WPF appliaciton i have expander
>>some content
<Expander ExpandDirection="Right" Header="" Margin="341,6,-6,0" BorderBrush="{x:Null}" Foreground="Black" Canvas.ZIndex="-1">
<StackPanel Background="#FFE2E2E2" Margin="-28,30,-4,-2" Width="175" Opacity=".8">
>>some content<<
</StackPanel>
</Expander>
</Grid>
</Window>
When you eject it covers the original content, its good, but content is invisibly covered if are expander is hidden too and content under it can not use.
My think is: If expander is hidden - it have z-index: -1 and normal content can use, if I eject it - expander have z-index:1
but I do not know how to do it, thank you for reply.

I got it.
Stackpanel normaly have zindex -1, and tools on my window working.
if i click to the stackpanel for open it,
stack panel get zindex +1, if i close it (i must click to expander button again) stackpanel get zindex -1
you can see at code
public int indexx = -1;
private void StackPanel_Click(object sender, RoutedEventArgs e)
{
if (indexx == 1)
{
indexx = -1;
Canvas.SetZIndex(panel, indexx);
}
else
{
indexx = 1;
Canvas.SetZIndex(panel, indexx);
}
}

Related

Capture swipe events on Grid without ListView with scrollbar getting in the way

I have a Grid that handles swipe events. On this Grid a ListView is placed. Unfortunately, if the ListView has its own scroll bar (bigger than the page) it "eats up" all the swipe events. It is not possible to capture swipe left or right swipe events on the parts of the screen where the ListView is.
The Grid with the ListView:
<Grid
Name="SwipingSurface"
Background="Transparent"
Height="657"
Margin="30">
(...)
<ListView
ShowsScrollingPlaceholders="True"
Grid.Row="1"
ItemsSource="{Binding MeditationDiary}"
FontFamily="Segoe WP"
Margin="0,45.5,0,0"
Grid.RowSpan="2"
d:LayoutOverrides="TopPosition, BottomPosition">
<ListView.ItemTemplate>
<DataTemplate>
[Grid and textblock template]
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
The code that handles swipe (right) events:
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
SwipingSurface.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;
SwipingSurface.ManipulationStarted += OnStarted;
SwipingSurface.ManipulationCompleted += OnManipulationCompleted;
}
public void OnStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
_initialPoint = e.Position;
}
public void OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
var currentPoint = e.Position;
if (_initialPoint.X - currentPoint.X >= Constants.SwipingTreshold)
{
// Do something
}
}
Is there a way to be able to handle swipe events on the Grid without the ListView getting in the way?
/edit Someone voted on this question since he or she found it unclear what is asked, so hereby a clarification: the code above generates the ListView below. It is possible to swipe left and notice the event if you swipe on History. But if you swipe on the ListView containing the content (only when it is longer than the page and you can scroll down) the swipe is not registered. I assume this is becaues the ListView is capturing the events.
Maybe adding ScrollViewer.HorizontalScrollBarVisibility="Disabled" to Your listView declaration could help. As an alternative You can try to modify the style of listView. Maybe you will find a scrollviewer there and then, disable it setting it property.

How to detect when ListView Reached to and end in Windows 10 Universal app development

I followed this link Detect when WPF listview scrollbar is at the bottom?
But ScrollBar.Scroll doesn't exist for ListView in Windows 10 .. how to achieve this requirement in windows 10
Thanks
Use the methods described here How can I detect reaching the end of a ScrollViewer item (Windows 8)?
If you want incremental loading there's a built-in solution for that. Otherwise go and traverse the visual tree for the scrollviewer object in the template.
You can do it by simply detecting VerticalOffset and ScrollableHeight of your ScrollViewer. Here is my simple code.
XAML:
<!--Apply ScrollViwer over the ListView to detect scrolling-->
<ScrollViewer Name="ContentCommentScroll" Grid.Row="2"
ViewChanged="ContentCommentScroll_ViewChanged" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<!--My Dynamic ListView-->
<ListView Name="MyDataList" ItemsSource="{Binding MyList}"
ItemTemplate="{StaticResource MyDataTemplate}"
ItemContainerStyle="{StaticResource myStyle}"/>
</ScrollViewer>
And code in its XAML.CS:
// Hold ScrollViwer
public ScrollViewer listScrollviewer = new ScrollViewer();
// Binded event, which will trigger on scrolling of ScrollViewer
private void ContentCommentScroll_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
Scrolling(ContentCommentScroll);
}
private void Scrolling(DependencyObject depObj)
{
ScrollViewer myScroll= GetScrollViewer(depObj);
// Detecting if ScrollViewer is fully vertically scrolled or not
if (myScroll.VerticalOffset == myScroll.ScrollableHeight)
{
// ListView reached at of its end, when you are scrolling it vertically.
// Do your work here here
}
}
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}
You can also apply similar logic to detect that if ListView Horizontally reached to its end.
You can wrap it with a ScrollViewer and name it. Then you can use some other methods.

WPF Expander - when GridSplitter used to manually resize row, row does not properly collapse

This is what I have
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="25"/>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Expander IsExpanded="False" Grid.Row="0" >
<DataGrid name="FirstGrid" />
</Expander>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" Height="5" />
<DataGrid Grid.Row="2" name="SecondGrid" />
When I click the expand button on the expander it correctly expands row 0 to the size of the DataGrid FirstGrid and it properly collapses the row as well. This does not work however if I expand the FirstGrid then manually resize that row by dragging the GridSplitter up or down and then pressing collapse button on the expander. What happens is that FirstGrid collapses but the row itself the FirstGrid is in does not. Any suggestions?
Thanks
Rob is right, once you move the gridsplitter, the Height of the first Row will not be Auto anymore, so it will not respond to the change in the expander size
In order for this to work you would need to add a behavior to the expander which will listen to the expander.expanded and collapsed event and update the grid row to be auto again. something like this:
public class GridColumnWidthReseterBehaviour : Behavior<Expander>
{
private Grid _parentGrid;
public int TargetGridRowIndex { get; set; }
protected override void OnAttached()
{
AssociatedObject.Expanded += AssociatedObject_Expanded;
AssociatedObject.Collapsed += AssociatedObject_Collapsed;
FindParentGrid();
}
private void FindParentGrid()
{
DependencyObject parent = LogicalTreeHelper.GetParent(AssociatedObject);
while (parent != null)
{
if (parent is Grid)
{
_parentGrid = parent as Grid;
return;
}
parent = LogicalTreeHelper.GetParent(AssociatedObject);
}
}
void AssociatedObject_Collapsed(object sender, System.Windows.RoutedEventArgs e)
{
_parentGrid.RowDefinitions[TargetGridRowIndex].Height= GridLength.Auto;
}
void AssociatedObject_Expanded(object sender, System.Windows.RoutedEventArgs e)
{
_parentGrid.RowDefinitions[TargetGridRowIndex].Height= GridLength.Auto;
}
}
And you use it like this:
<Expander ...>
<interactivity:Interaction.Behaviors>
<behaviors:GridColumnWidthReseterBehaviour TargetGridRowIndex="0"></behaviors:GridColumnWidthReseterBehaviour>
</interactivity:Interaction.Behaviors>
...
As soon as you move the gridsplitter, the Height of the first Row will not be Auto anymore, but a certain value, like 70. After that it doesn't matter if some child in that row changes its height.
Combining a splitter with some auto-sized child/row is very difficult; you can take a look at the side expander in Microsoft Outlook; i suspect that this is what you want. If so, you shouldn't use an expander, because a regular expander contains a StackPanel so its children are always auto-sizing in the expand direction. I'm not sure what you want, but i think going for a custom control is your best option.

How to attach a Thumb to a TextBlock?

I have the following XAML:
<Window x:Class="thumb_test.MainWindow" Title="MainWindow" ... >
<Grid>
<Canvas>
<Thumb Canvas.Top="25" Canvas.Left="25" Width="50" Height="50"
Name="_thumb1" DragStarted="ThumbStart" DragDelta="ThumbMoved" >
</Thumb>
</Canvas>
</Grid>
</Window>
And the following is the corresponding code-behind:
void ThumbStart(object sender, DragStartedEventArgs e)
{
_originalLeft = Canvas.GetLeft(_thumb1);
_originalTop = Canvas.GetTop(_thumb1);
}
void ThumbMoved(object sender, DragDeltaEventArgs e)
{
double left = _originalLeft + e.HorizontalChange;
double top = _originalTop + e.VerticalChange;
Canvas.SetLeft(_thumb1, left);
Canvas.SetTop(_thumb1, top);
_originalLeft = left;
_originalTop = top;
}
The above displays a rectangle, which can be dragged around on the canvas.
My question: How can I associate this Thumb with a TextBlock, such that the Thumb overlays the TextBlock (with the Thumb being transparent) and I can drag the TextBlock around? (PS: Believe me, what I have tried so far is not worth showing here.)
My ultimate goal is to be able to drag TextBlocks around, so I am open to other approaches. I would like to operate on a Canvas, though.
I am using VS2010 on Win 7, with .NET 4.0.
have you read Dragging Elements in a Canvas ?
or this easy way(that i never saw until now -google) How to make any UI element drag-able using Behaviors in WPF

Keyboard overlaps textbox

I'm using a list of textboxes for a registering document in a WP8 app.
The number of textboxes is quite large, so the user has to scroll between them.
To navigate between one field to another, I added two applicationbarIcons, next and previous. Pressing on next will change the focus to the next textbox from list, and scroll the content of the scroll viewer with the height of the textbox (in this case 50).
However, sometimes, when switching the focus to the element bellow, the keyboard covers the text box. (the content doesn't scroll up).
Is there a way to force the textbox to move above the keyboard, even if it is in a scroll view?
<ScrollViewer x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.STRING_CONTACT}" Margin="10,5" FontWeight="SemiBold" Foreground="#878780"></TextBlock>
<StackPanel Margin="10,5" Height="190" Background="#F4F3F4">
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="firstNameTxt" BorderThickness="0" Background="Transparent" InputScope="PersonalFullName"><TextBox>
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="lastNameTxt" BorderThickness="0" Background="Transparent" InputScope="PersonalFullName"></my:DefaultTextBox>
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="MobileTxt" BorderThickness="0" InputScope="Number" Background="Transparent" ></TextBox>
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="EmailTxt" BorderThickness="0" Background="Transparent">
</StackPanel>
</ScrollViewer>
Code behind:
void left_Click(object sender, EventArgs e)
{
int index = this.controls.IndexOf(currentControl) - 1;
if (index == -1)
{
this.Focus();
return;
}
currentControl = this.controls[index];
ContentPanel.ScrollToVerticalOffset(ContentPanel.VerticalOffset - 50);
currentControl.Focus();
}
This is a common issue on WP8. When a textbox is focused, it will translate Application 's RootVisual to bring it into view. This doesn't work well in some cases (when clipboard is on, or in your case). A workaround is manually translating RootVisual to a desired vertical offset on GotFocus and LostFocus events of TextBox.
private void TranslateRootVisualY(int yNew)
{
var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
rootFrame.RenderTransform = new CompositeTransform() {TranslateY = yNew};
}
In your case, you can eliminate the automatic translation and make ScrollViewer scroll to desired offset in GotFocus event:
private void firstNameTxt_GotFocus_1(object sender, RoutedEventArgs e)
{
TranslateRootVisualY(0);
Dispatcher.BeginInvoke(() =>{
double destOffset;
//...calculate destination offset
ContentPanel.ScrollToVerticalOffset(destOffset);
});
}
destOffset can be calculated from sender and other function like GetRectFromCharacterIndex

Categories

Resources