UWP Tab View not responding - c#

I have a page with a Tab View. Inside every tab is another page. Whenever I try to interact with the tab, nothing works. I tried interacting with it with SettingsPage as the content, and it worked.
MainPage - contains the tabs
TabbedMainPage - contains the workspace
SettigsPage - contains settings
MainPage:
private void TabView_AddTabButtonClick(TabView sender, object args)
{
sender.TabItems.Add(CreateNewTab());
}
public TabViewItem OpenSettingsTab()
{
TabViewItem newItem = new TabViewItem();
newItem.Header = "Settings";
newItem.IconSource = new Microsoft.UI.Xaml.Controls.SymbolIconSource() { Symbol = Symbol.Setting };
Frame frame = new Frame();
frame.Navigate(typeof(SettingsPage));
newItem.Content = frame;
TabbedView.UpdateLayout();
return newItem;
}
public void CreateSettingsTab()
{
TabbedView.TabItems.Add(OpenSettingsTab());
TabbedView.UpdateLayout();
TabbedView.SelectedIndex = TabbedView.TabItems.Count - 1;
}
public TabViewItem CreateNewTab()
{
TabViewItem newItem = new TabViewItem();
newItem.Header = "New Tab";
newItem.IconSource = new Microsoft.UI.Xaml.Controls.SymbolIconSource() { Symbol = Symbol.Document };
Frame frame = new Frame();
frame.Navigate(typeof(TabbedMainPage));
newItem.Content = frame;
TabbedView.UpdateLayout();
return newItem;
}
private void TabbedView_Loaded(object sender, RoutedEventArgs e)
{
var S = sender as TabView;
if (S.TabItems.Count == 0)
{
S.TabItems.Add(CreateNewTab());
}
TabbedView.UpdateLayout();
}
TabbedMainPage has the following components: ColorPicker, DropDownButton, MenuBar, Border, Button, CheckBox, ComboBox, Flyout, Grid, Image, MenuFlyout, Pivot, PivotItem, StackPanel, TextBlock, TextBox, Flyout, Popup, RichEditBox, ScrollViewer, Slider, ToggleButton and Tooltip.
I think it might be caused by overloading with components, but I'm not sure. I also have these in my code:
MediaElement ME;
SpeechSynthesizer Synth;
public StorageFile TXTFile;
public IRandomAccessStream RAS;
private readonly PrintHelperOptions PP = new PrintHelperOptions();
var LS = ApplicationData.Current.LocalSettings;
var TB = ApplicationView.GetForCurrentView().TitleBar;
var CTB = CoreApplication.GetCurrentView().TitleBar;

I managed to fix the bug by removing the Pivot from the toolbar. It was interfering with the tab functionality, so I merged all the items together.

Related

Word VSTO add-in: Change task pane width on position changed

I have a UserControl which by default is anchored at the bottom like this:
var customTaskPaneContent = new CustomTaskPaneContent(jobId, _ipcClient, document, AddCustomTaskPane);
var customTaskPane = CustomTaskPanes.Add(customTaskPaneContent, CustomTaskPaneTitle, document.ActiveWindow);
customTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionBottom;
customTaskPane.Height = 130;
customTaskPane.Visible = true;
customTaskPane.VisibleChanged += CustomTaskPane_VisibleChanged;
customTaskPane.DockPositionChanged += CustomTaskPane_DockPositionChanged;
private void CustomTaskPane_DockPositionChanged(object sender, EventArgs e)
{
var customTaskPane = sender as Microsoft.Office.Tools.CustomTaskPane;
if(customTaskPane != null)
{
if (customTaskPane.DockPosition == Office.MsoCTPDockPosition.msoCTPDockPositionFloating)
{
//ATTEMPT 1
//customTaskPane.Width = 1000;
//ATTEMPT 2
var userControl = customTaskPane.Control;
var size = new System.Drawing.Size(1500, 400);
userControl.Size = size;
}
}
}
When I drag the panel and its position changes to msoCTPDockPositionFloating the assigned dimensions are too small and I would like to change its width.
I have made several attempts but the dimensions are never changed. Which is the correct way to change the Width size?
Try to change the Size property of the content as well in the following way:
private void myCustomTaskPane_DockPositionChanged(object sender, EventArgs e)
{
Microsoft.Office.Tools.CustomTaskPane taskPane =
sender as Microsoft.Office.Tools.CustomTaskPane;
if (taskPane != null)
{
// Adjust sizes of user control and flow panel to fit current task pane size.
MyUserControl userControl = taskPane.Control as MyUserControl;
System.Drawing.Size paneSize = new System.Drawing.Size(taskPane.Width, taskPane.Height);
userControl.Size = paneSize;
userControl.FlowPanel.Size = paneSize;
// Adjust flow direction of controls on the task pane.
if (taskPane.DockPosition ==
Office.MsoCTPDockPosition.msoCTPDockPositionTop ||
taskPane.DockPosition ==
Office.MsoCTPDockPosition.msoCTPDockPositionBottom)
{
userControl.FlowPanel.FlowDirection =
System.Windows.Forms.FlowDirection.LeftToRight;
}
else
{
userControl.FlowPanel.FlowDirection =
System.Windows.Forms.FlowDirection.TopDown;
}
}
}
This code example assumes that the task pane contains a UserControl named MyUserControl, and the UserControl contains a FlowLayoutPanel named FlowPanel.
See CustomTaskPane Interface for the full sample code.

UWP Graphic glitch when selecting a MenuItem of a NavigationView generated in code behind

I have a NavigationView and some NavigationViewItems generated in code behind.
From the code I was trying to select one NavigationViewItem that was the default one showed to the user at launch and I expirienced a strange behavior
(this behavior doesn't happen if you select a NavigationViewItem that was generated in the xaml).
When I launch the app I can't see the selection (the accent colored rectangle on the left of the NavigationViewItem) but when I click another NavigationViewItem the rectangle shows up and start the animation that moves it from the old NavigationViewItem to the new one.
I followed the same code that I found on the documentation with the exception that in the documentation they select a NavigationViewItem that was generated in the xaml.
https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/navigationview
Here is the code to reproduce the problem (minimum version and target version of the project: Win10 FCU Build 16299)
XAML:
<NavigationView x:Name="navView" Loaded="navView_Loaded">
</NavigationView>
<Button Content="Select Mail" Click="button_Click" HorizontalAlignment="Center"/>
c#:
private void navView_Loaded(object sender, RoutedEventArgs e)
{
navView.MenuItems.Add(new NavigationViewItem()
{ Content = "Home", Icon = new SymbolIcon(Symbol.Home), Tag = "home" });
navView.MenuItems.Add(new NavigationViewItem()
{ Content = "My content", Icon = new SymbolIcon(Symbol.Folder), Tag = "content" });
navView.MenuItems.Add(new NavigationViewItem()
{ Content = "Mail", Icon = new SymbolIcon(Symbol.Mail), Tag = "mail" });
foreach (NavigationViewItemBase item in navView.MenuItems)
{
if (item is NavigationViewItem && item.Tag.ToString() == "home")
{
navView.SelectedItem = item;
break;
}
}
}
private void button_Click(object sender, RoutedEventArgs e)
{
navView.SelectedItem = navView.MenuItems.ElementAt(2);
}
The problem is that you have do more things in the navView_Loaded cause SelectionIndicator animation terminate. You could add await Task.Delay(500); before setting NavigationView selectedItem to verify this.
await Task.Delay(500);
foreach (NavigationViewItemBase item in navView.MenuItems)
{
if (item is NavigationViewItem && item.Tag.ToString() == "home")
{
navView.SelectedItem = item;
(navView.SelectedItem as NavigationViewItem).IsSelected = true;
break;
}
}
For your scenario, you could add the MenuItems in the Loading event handler method and set the select item in the Loaded event handler method.
private void navView_Loaded(object sender, RoutedEventArgs e)
{
foreach (NavigationViewItemBase item in navView.MenuItems)
{
if (item is NavigationViewItem && item.Tag.ToString() == "home")
{
navView.SelectedItem = item;
(navView.SelectedItem as NavigationViewItem).IsSelected = true;
break;
}
}
}
private void navView_Loading(FrameworkElement sender, object args)
{
navView.MenuItems.Add(new NavigationViewItem()
{ Content = "Home", Icon = new SymbolIcon(Symbol.Home), Tag = "home" });
navView.MenuItems.Add(new NavigationViewItem()
{ Content = "My content", Icon = new SymbolIcon(Symbol.Folder), Tag = "content" });
navView.MenuItems.Add(new NavigationViewItem()
{ Content = "Mail", Icon = new SymbolIcon(Symbol.Mail), Tag = "mail" });
}

How to handle the Tap of a ViewCell defined in code in Xamarin.Forms?

I have a multiple ViewCell and ImageCell subclasses inside a TableView.
I would like to execute some code when the user taps the cell. The whole cell highlights whenever it's touched, but I don't see any event handler to use here.
Isn't there a XAML Tapped equivalent for this but in code only?
private void SetTableView()
{
Content = new TableView
{
HasUnevenRows = true,
Intent = TableIntent.Menu,
Root = new TableRoot()
{
new TableSection()
{
new ProfileCell(ImageSource.FromFile("profile_placeholder.png"), "Casa de Férias")
},
new TableSection()
{
new InfoCell()
{
Type = InfoCellTypes.Pending,
Text = "Avaliação do Imóvel",
Detail = "Estado do Processo"
}
}
}
};
}
I'm sure there must be some API that handles this. Maybe I'm just not looking in the right place?
Thank you!
This can be accomplished by adding a TapGestureRecognizer to the cell's view layout.
var absoluteLayout = new AbsoluteLayout
{
Children =
{
photo,
editImage,
label
}
};
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.NumberOfTapsRequired = 1;
tapGestureRecognizer.Tapped += (s, e) => {
// handle the tap
};
absoluteLayout.GestureRecognizers.Add(tapGestureRecognizer);
View = absoluteLayout;
EDIT:
Or, a better alternative, using the Tapped property of the ViewCell, so it doesn't break the "Tap Animation":
Tapped += new EventHandler((e, s) => {
if (command.CanExecute(null))
{
command.Execute(null);
}
});

Can't navigation between xaml in frame?

I have got issues . Why did not it navigate to other xaml? Where is wrong?
So, I was trying to make it that can navigated between two or more xaml in a frame.
Here is link : https://github.com/Englbach/MutiViewInRootPage
<SplitView.Content>
<!-- OnNavigatingToPage we synchronize the selected item in the nav menu with the current page.
OnNavigatedToPage we move keyboard focus to the first item on the page after it's loaded. -->
<Frame x:Name="AppShellFrame">
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition>
<NavigationThemeTransition.DefaultNavigationTransitionInfo>
<EntranceNavigationTransitionInfo />
</NavigationThemeTransition.DefaultNavigationTransitionInfo>
</NavigationThemeTransition>
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
</SplitView.Content>
public static AppShell Current = null;
public List<NavMenuItem> NavList { get; } = new List<NavMenuItem>(new[]
{
new NavMenuItem()
{
Symbol = Symbol.Add,
Label = "Add feed",
DestPage = typeof(RootPages),
Arguments = typeof(AddFeedView)
},
new NavMenuItem()
{
Symbol = Symbol.Edit,
Label = "Edit feeds",
DestPage = typeof(RootPages),
Arguments = typeof(EditFeedView)
}
});
public AppShell()
{
this.InitializeComponent();
Current = this;
}
private void NavMenuList_ItemInvoked(object sender, ListViewItem e)
{
NavMenuList.SelectedIndex = -1;
var item = (NavMenuItem)((NavMenuListView)sender).ItemFromContainer(e);
if(item!=null)
{
AppFrame.Navigate(typeof(RootPages), item.Arguments);
}
}
You probably followed the official Navigation menu (XAML) sample to design your layout.
There are two tiny problems in your demo.
Each time the items in the NavMenuList is clicked, the NavMenuList_ItemInvoked event in the AppShell.xaml.cs should be triggered. And in this event, you navigated again and again to your RootPages, and together pass the navigation parameter(item.Arguments) to the RootPages like this AppFrame.Navigate(typeof(RootPages), item.Arguments);, and the argument is actually your destination.
You can modify the code here like this:
private void NavMenuList_ItemInvoked(object sender, ListViewItem e)
{
//NavMenuList.SelectedIndex = -1;
var item = (NavMenuItem)((NavMenuListView)sender).ItemFromContainer(e);
if (item != null)
{
//AppFrame.Navigate(typeof(RootPages), item.Arguments);
if (item.DestPage != null &&
item.DestPage != this.AppFrame.CurrentSourcePageType)
{
this.AppFrame.Navigate(item.DestPage, item.Arguments);
}
}
}
Then here comes the second problem, as I said, the Arguments should be navigation parameter, for example, I navigate to AddFeedView page and I want to send a message "balalala", then we can code like this: AppFrame.Navigate(typeof(AddFeedView), "balalala");. This means, you confused with your DestPage and Arguments.
You can modify your NavList like this:
public List<NavMenuItem> NavList { get; } = new List<NavMenuItem>(new[]
{
new NavMenuItem()
{
Symbol = Symbol.Add,
Label = "Add feed",
DestPage = typeof(AddFeedView),
Arguments = typeof(RootPages)
},
new NavMenuItem()
{
Symbol = Symbol.Edit,
Label = "Edit feeds",
DestPage = typeof(EditFeedView),
Arguments = typeof(RootPages)
}
});
In additional, if you want your AppFrame to navigate to the RootPages at first by default, you can code like this:
public AppShell()
{
this.InitializeComponent();
Current = this;
AppFrame.Navigate(typeof(RootPages));
}

Displaying a Xamarin Forms StackList doesn't render properly

While learning how to use Xamarin Forms and StackLayouts I'm having trouble rendering the items.
I'm trying to bind a collection of somethings to a StackLayout. The binding (more or less) works. The visual render is wrong.
For this question, I've picked some random thing (in this case, credit cards) to highlight my experimenting.
This is what I'm rending:
Notice how each custom row looks to be fixed height's or something?
Show me the code! Ok, so this is what I've done:
First, the page:
public class MyPage : ContentPage
{
protected override void OnAppearing()
{
var creditCards = new SomeFakeListOfCreditCards();
var stackLayout = new CreditCardStackLayout(creditCards);
Contet = stackLayout;
}
}
Now for the custom control...
public class CreditCardStackLayout : StackLayout
{
public CreditCardStackLayout(IEnumerable<CreditCard> creditCards)
{
// Note: credit cards can be null (because we don't have any).
CreateContent(creditCards);
}
private void CreateContent(IEnumerable<CreditCard> creditCards)
{
VerticalOptions = LayoutOptions.Center;
Children.Add(TitleLabel);
if (creditCards == null)
{
Children.Add(NoCreditCardLabel);
}
else
{
Children.Add(CreateCreateCardList(creditCards));
}
}
private static ListView CreateCreateCardList(IEnumerable<CreditCard> creditCards)
{
if (creditCards == null)
{
throw new ArgumentNullException("creditCards");
}
// Project the credit cards into a list view model.
var viewModel = creditCards.Select(x => new CreditCardViewModel(x));
return new ListView
{
ItemsSource = viewModel,
ItemTemplate = new DataTemplate(typeof(CreditCardViewCell))
};
}
private Label TitleLabel
{
get
{
return new Label
{
HorizontalOptions = LayoutOptions.Center,
Text = "A list of credit cards"
};
}
}
private Label NoCreditCardLabel
{
get
{
return new Label
{
Text = "You have no real credit cards on file."
};
}
}
}
So far so good.. Now for the binding..
public class CreditCardViewCell : ViewCell
{
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
var stackLayout = new StackLayout
{
BackgroundColor = new Color(46, 81, 163),
VerticalOptions = LayoutOptions.Center,
Children =
{
NameLabel,
TypeImage,
NumberLabel,
ExpiresOnLabel,
RemoveButton
}
};
View = stackLayout;
}
private Label NameLabel
{
get
{
var label = new Label
{
FontSize = 14
};
label.SetBinding(Label.TextProperty, "Name");
return label;
}
}
private Label NumberLabel
{
get
{
var label = new Label
{
FontSize = 14
};
label.SetBinding(Label.TextProperty, "Number");
return label;
}
}
private Label ExpiresOnLabel
{
get
{
var label = new Label
{
FontSize = 14
};
label.SetBinding(Label.TextProperty, "ExpiresOn");
return label;
}
}
private Image TypeImage
{
get
{
var creditCardModel = (CreditCardViewModel)BindingContext;
string fileName = null;
switch (creditCardModel.Type)
{
case "Visa":
fileName = "visa.png";
break;
default:
fileName = "mastercard.png";
break;
}
var image = new Image
{
Source = ImageSource.FromFile("Icons/" + fileName)
};
return image;
}
}
private Button RemoveButton
{
get
{
var button = new Button
{
//Image = "Icons/remove.png"
Text = "Remove"
};
button.Clicked += async (object sender, EventArgs e) =>
{
// TODO when I figure out how to do this stuff.
int i = 0;
i++;
};
return button;
}
}
}
}
Also, please do not suggest going to a XAML file, I'm trying to learn this stuff programmatically.
Side thought: I wish I could turn on borders so I can see how things are laid out.
Use ListView's HasUnevenRows property. Change this:
return new ListView
{
ItemsSource = viewModel,
ItemTemplate = new DataTemplate(typeof(CreditCardViewCell))
};
to:
return new ListView
{
HasUnevenRows = true,
ItemsSource = viewModel,
ItemTemplate = new DataTemplate(typeof(CreditCardViewCell))
};
By default Xamarin.Forms ListView row size is fixed and set to the same value for every row (RowHeight property). With this configuration row auto-sizing won't work, but it also gives best ListView performance.
You can auto-size rows by setting ListView's HasUnevenRows property to true. It allows modifying ViewCell size by setting ViewCell's RowHeight property (eg. in OnBindingContextChanged override). In newer Xamarin.Forms versions it also sizes ViewCells automatically (on older it worked only on Android).

Categories