Cannot remove controls after navigating back to page (Win 8 app) - c#

i have a tablet app (windows 8 app) with a starting homepage.xaml . There i have ListView binded to a ObservableCollection with UpdateSourceTrigger set to PropertyChanged ... in this list i create dynamically Panels(with delete button). When i create the button and then i click the delete button everything works fine .. the panel dissapears with nice animation. However, when i create a new panel.. then i navigate to a different page and go back to homepage, click delete to any of those panels they dont dissapear .. But if navigate again to another page and then i go back. The panel is removed. I tried to debug that collection everything looks fine. Tried to change UpdateSourceTrigger to Explicit and call it manually but no success. Thanks for help
ListView Xaml in HomePage.xaml
<ListView x:Name="CListView" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="40, 0, 50, 50"
SelectionMode="None" IsItemClickEnabled="True" ItemClick="CListView_OnItemClick"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollMode="Auto"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.ZoomMode="Disabled"
ScrollViewer.IsHorizontalScrollChainingEnabled="True"
ItemsSource="{Binding Path=ClControls, ElementName=HomePageElementName, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemContainerStyle>
HomePage.xaml.cs
OnItemRemove
public ObservableCollection<IClControl> ClControls
{
get { return _clEvents; }
set
{
_clEvents = value;
OnPropertyChanged();
}
}
private async void ClControl_OnItemRemove(object sender, ClControlRemoveItemArgs e)
{
var control = sender as ClControl;
if (control == null)
return;
var clEvent = e.ClEventInfo;
// control.OnItemRemove -= ClControl_OnItemRemove;
if (ClControls.Contains(control))
{
ClControls.Remove(control);
}
if (SessionHolder.Instance.ClControls.Contains(control))
{
SessionHolder.Instance.ClControls.Remove(control);
}
await clEvent.Delete();
}

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.

UserControl hidden, Zindex misused?

In my main page I try to show a list of stuff, and on this stuff a userControl as an overlay. In fact I never see it. (In the design view, my userControl is oaky)
XAML MainPage
<Grid>
<Grid x:name="MyPage">
<!-- All this part is visible -->
//Button
//Button
//nice Pic
//Button
</Grid>
<cat:CatPagecontrol x:Name="CatTool" Visibility="Visible" HorizontalAlignment="Center" VerticalAlignment="Center">
<cat:CatPagecontrol.Transitions>
<TransitionCollection>
<PopupThemeTransition/>
</TransitionCollection>
</cat:CatPagecontrol.Transitions>
</cat:CatPagecontrol>
<!-- EDIT I remove the Grid "CatGrid" And the ZIndex -->
</Grid>
I try to switch the ZIndex, no results.
C# File
public MainView()
{
this.CatTool = new CatPagecontrol();
//this.CatTool.Visibility = Visibility.Collapsed;
}
private void showCatSelector()
{
this.CatTool.Visibility = Visibility.Visible;
}
After that I need that one of my buttons show the overlay when clicked.
If you know how to show it, I'm yours. Thanks.
edit : solution find.
Voila !
I've find my problem :
public CatPagecontrol()
{
this.InitializeComponent();
}
I just Initialized in the correct section.

WPF MVVM Prevent tab change

I am having a WPF Tab control with two tabs called "OFFLINE" & "ONLINE". When "ONLINE" tab click, I need to chek whether application is in online status or not.If (status ! = online)
display error message and prevent displaying "ONLINE" (2nd) tab and go to "OFFLINE" tab.
VIEW.XAML
<TabControl Name="dashboardTabControl" SelectedIndex="{Binding SelectedTabIndex,Mode=TwoWay}">
<TabItem Header="Local Dashboard">
<views:OfflineDashboard DataContext="{Binding OfflineDashboardViewModel}"/>
</TabItem>
<TabItem Header="Online Dashboard">
<views:OnlineDashboard DataContext="{Binding OnlineDashboardViewModel}"/>
</TabItem>
</TabControl>
VIEWMODEL
public int SelectedTabIndex
{
get
{
return this.selectedTabIndex;
}
set
{
if (value == 1 && !applicationData.IsApplicationOnline())
{
this.SelectedTabIndex = 0;
}
else
{
this.selectedTabIndex = value;
}
// TODO : According to the selected tab index , populate ONLINE/OFFLINE
viewmodels
NotifyPropertyChange("SelectedTabIndex");
}
}
Question : Although i checked status and set tab to 0, it doesn't work.
always onclick of 2nd tab it will displayed ONLINE tab.
I would do this the other way around.
Have the ViewModel listen for network changes and expose a bool property Online.
Bind the Enabled property of the Tabpages to this bool.
That way you do not pollute the ViewModel with UI code.
Finally I found a solution for my problem:
XAML
<TabControl Name="dashboardTabControl" Margin="0,5,0,0" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TabItem Header="Local Dashboard" IsSelected="{Binding IsOnline,Converter={StaticResource invertBoolConverter}}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<views:OfflineDashboard DataContext="{Binding OfflineDashboardViewModel}"/>
</TabItem>
<TabItem Header="Online Dashboard" IsSelected="{Binding IsOnline}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<views:OnlineDashboard DataContext="{Binding OnlineDashboardViewModel}"/>
</TabItem>
Now I am using IsSelected property of TabItem, instead of SelectedIndex
VIEWMODEL
public bool IsOnline
{
get
{
return isOnline;
}
set
{
// When ONLINE tab click, check whether application is online,
// if not, do not display ONLINE tab
if (value && !applicationData.IsApplicationOnline())
{
isOnline = false;
return;
}
else
{
isOnline = value;
}
LoadTabContent();
NotifyPropertyChange("IsOnline");
}
}
This solved my problem.
You should implement INotifyPropertyChanged in your ViewModel. After changing the SelectedTabIndex notify View that selected index of tab control has been changed via PropertyChanged event of INotifyPropertyChanged.
And in your XAML do
SelectedIndex="{Binding SelectedTabIndex,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}

How to bind a usercontrol property to Listbox

I am having an issue with using a Listbox in my parent project to display a property defined in a user control. To be more specific, I have created a user control which contains a webbrowsercontrol, and I have defined a property called History which contains the history of urls visited during a browsing session. I also have a parent project, which is linked to this user control, in which I am attempting to bind the History property to a Listbox. The point is for someone to be able to see the history urls in a Listbox defined in this parent project, where the history urls are populated by binding to the user control's History property.
Below is my code outlining what I am trying to do:
User Control FullWebBrowser.xaml.cs
public partial class FullWebBrowser : UserControl
{
//ctr
public FullWebBrowser()
{
InitializeComponent();
//for FullWebBrowser.xaml ContentGrid
ContentGrid.DataContext = this;
}
#region Fields
//The navigation urls of the browser.
private readonly Stack<Uri> _NavigatingUrls = new Stack<Uri>();
//The history for the browser
private readonly ObservableCollection<string> _History = new ObservableCollection<string>();
/// <summary>
/// Gets the History property for the browser.
/// </summary>
public ObservableCollection<string> History
{
get { return _History; }
}
The _NavigatingUrls stack is for the forward and back button implementation, which is working fine, and the _History observablecollection contains the urls from the webbrowsing session shown as follows
//If the navigated uri is not in thehistory, add it
if (!_History.Contains(e.Uri.ToString()))
_History.Add(e.Uri.ToString());
These seem to be working properly, as I have implemented the forward and back buttons and they work ok. The issue is that I cannot properly bind the History property defined in the FullWebBrowser.xaml.cs to my parent project which contains a Listbox. This is shown as follows
HistoryPage.xaml
xmlns:my="clr-namespace:FullBrowserControl;assembly=FullBrowserControl">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="QUEST">
<!--Pivot item one-->
<controls:PivotItem Header="today">
<Grid/>
</controls:PivotItem>
<!--Pivot item two-->
<controls:PivotItem Header="week">
<Grid/>
</controls:PivotItem>
<!--Pivot item three-->
<controls:PivotItem Header="all">
<StackPanel>
<ScrollViewer>
<ListBox x:Name="ListBox" ItemsSource="{Binding}"
SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=History}" Height="Auto"/>
<TextBlock Foreground="{StaticResource PhoneSubtleBrush}"
Text="{Binding Modified, Converter={StaticResource DateConverter}}"
Margin="24,0,0,12"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Scrollviewer>
</StackPanel>
<!--<Grid/>-->
</controls:PivotItem>
</controls:Pivot>
</Grid>
Note, the dateconverter is ok. Here I am trying to implement a Listbox which shows the url with a timestamp below it.
The code behind for this parent project page is as follows
Historypage.xaml.cs
public partial class HistoryPage : PhoneApplicationPage
{
//Temporary State
public static readonly Setting<int> CurrentHistoryIndex = new Setting<int>("CurrentHistoryIndex", -1);
private FullWebBrowser browser = new FullWebBrowser();
public HistoryPage()
{
InitializeComponent();
//create new instance of FullWebBrowser user control?
this.browser = new FullWebBrowser();
this.DataContext = browser;
//browser.DataContext = this;
//this.DataContext = browser.History;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
//Clear the selection so selecting the same item twice in a row will still raise the SelectedChanged event
CurrentHistoryIndex.Value = -1;
this.ListBox.SelectedIndex = -1;
}
void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListBox.SelectedIndex >= 0)
{
//navigate to the page containing the user control for the selected item
//how to navigate to Mainpage.xaml and load webbrowsercontrol with selected url??
CurrentHistoryIndex.Value = ListBox.SelectedIndex;
this.NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
}
So this is my basic implementation. No matter what I try I cannot get the Listbox in Historypage to bind to the History property in the FullWebBrowser user control contained outside of the project, I have referenced the FullWebBrowser control using the references option in the solution explorer, in a using declaration at the top of Historypage.xaml.cs, and by an xmlns statement at the top of HistoryPage.xaml
Any assistance with how this may be accomplished would be greatly appreciated! I have been working on this for a couple weeks and cannot find the solution anywhere, even prowling other's posts. I must implement this solution ASAP! thanks for all your help in advance. Please include code to accomplish this, it would help so much to see how this is implemented for future reference!
The DataContext of Your ListBox is FullWebBrowser, therefore your binding should be as follows:
<ListBox x:Name="ListBox" ItemsSource="{Binding Path=History}"/>
To solve this kind of problem yourself try debugging, breakpoint your code then inspect the DataContext properties of the various elements in your UI.

C#/WPF: Why is tab not focusing properly

I have a tab control
<TabControl Height="Auto" Grid.Row="1" ItemsSource="{Binding Tabs}" IsSynchronizedWithCurrentItem="True">
That is bound to Tabs in the ViewModel. I also used CollectionViewSource to focus tabs
protected ObservableCollection<TabViewModel> _tabs;
protected ICollectionView _tabsViewSource;
public ObservableCollection<TabViewModel> Tabs
{
get { return _tabs; }
}
public void OnTabsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null && e.NewItems.Count > 0)
foreach (TabViewModel tab in e.NewItems)
{
tab.CloseRequested += OnCloseRequested;
_tabsViewSource.MoveCurrentTo(tab); // focus newly created tab
}
if (e.OldItems != null && e.OldItems.Count > 0)
foreach (TabViewModel tab in e.OldItems)
tab.CloseRequested -= OnCloseRequested;
}
When I have more that 1 tab, when I create new Tabs, tabs are focused properly
when there are no tabs, new tabs don't seem to be focused properly. notice the tab header
how might I fix this? or what is causing this behavior? the text box (tab content) is shown but the header don't render like its selected
UPDATE
It works with a fresh file/project ... hmm ... must be some related code ... I might redo that part ...
IsSynchronizedWithCurrentItem="True" has no meaning unless you bind your TabControl.ItemsSource to an ICollectionView.
I can't tell if changing your binding from ObservableCollection to ICollectionView will solve your problem, but that is how I have setup my databound tabcontrol.
An alternative could be to expose a new property
public TabViewModel CurrentTabViewModel
{
get
{
return _tabs.CurrentItem as TabViewModel:
}
set
{
_tabs.MoveCurrentTo(value);
}
}
and bind TabControl's SelectedItem to CurrentTabViewModel
<TabControl SelectedItem="{Binding Path=CurrentTabViewModel}" ... />
Without the code, that initializes the single-tab-collection, it's just guessing.
A Workaround for you would be setting SelectedIndex of the tabView = 0 -> first tab is selected initially.
<TabControl Height="Auto"
Grid.Row="1"
ItemsSource="{Binding Tabs}"
IsSynchronizedWithCurrentItem="True"
SelectedIndex="0">

Categories

Resources