Is there any way to create new tabItem in TabControl WPF? - c#

I made a code in WinForm. It works.
I dragged xml file and dropped to tabPage.
private TextEditorControl AddNewTextEditor(string title)
{
var tab = new TabPage(title);
var editor = new TextEditorControl();
editor.Dock = System.Windows.Forms.DockStyle.Fill;
editor.IsReadOnly = false;
editor.Document.DocumentChanged +=
new DocumentEventHandler((sender, e) => { SetModifiedFlag(editor, true); });
// When a tab page gets the focus, move the focus to the editor control
// instead when it gets the Enter (focus) event. I use BeginInvoke
// because changing the focus directly in the Enter handler doesn't
// work.
tab.Enter +=
new EventHandler((sender, e) => {
var page = ((TabPage)sender);
page.BeginInvoke(new Action<TabPage>(p => p.Controls[0].Focus()), page);
});
tab.Controls.Add(editor);
fileTabs.Controls.Add(tab);
if (_editorSettings == null) {
_editorSettings = editor.TextEditorProperties;
OnSettingsChanged();
} else
editor.TextEditorProperties = _editorSettings;
return editor;
}
But WPF is a bit dirrenet.
Can I change the code for WPF?? or other way..? Thanks for your help.

You can do it this way:
Suppose you have this TabControl with TabItem A and B and a Button for adding TabItem
<StackPanel>
<TabControl x:Name="TabControl">
<TabItem Header="A"/>
<TabItem Header="B"/>
</TabControl>
<Button Content="Add New Tab Item" Click="ButtonBase_OnClick"/>
</StackPanel>
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var tabItem = new TabItem { Header = "C" };
TabControl.Items.Add(tabItem);
}
After clicking the button you will be added another TabItem (C)

Related

How to remove selected stackpanel using context menu in wpf

I have a StackPanel with children. The StackPanel children are also StackPanel. Children StackPanel is added by dynamically at runtime. I have a context menu with delete header. When I click the delete menu the selected stack children will be deleted. I don't have any idea to remove the StackPanel children by using the context menu. Please, anyone, guide me to resolve this. My sample code is as below,
<StackPanel x:Name="mainPanel" Background="#F0F0F0">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Click="ParentContextMenu_Click" Header="Add Stackpanel" />
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
Code behind
public partial class MainView : Window
{
ContextMenu contextMenu;
MenuItem menuItem;
public MainView()
{
InitializeComponent();
contextMenu = new ContextMenu();
menuItem = new MenuItem();
menuItem.Header = "Delete Panel";
menuItem.Click += ChildContextMenu_Click;
contextMenu.Items.Add(menuItem);
}
private void ChildContextMenu_Click(object sender, RoutedEventArgs e)
{
}
private void ParentContextMenu_Click(object sender, RoutedEventArgs e)
{
StackPanel stack = new StackPanel()
{
Name = "childStack"
Height = 100,
Width = 100,
Background = Brushes.White,
Margin = new Thickness(15, 15, 0, 10),
ContextMenu = contextMenu
};
mainPanel.Children.Add(stack);
}
}
I have tried like this also, but is not deleted.
mainPanel.Children.Remove((StackPanel)this.FindName("childStack"));
This should work:
private void ChildContextMenu_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi != null)
{
ContextMenu cm = mi.Parent as ContextMenu;
if (cm != null)
{
StackPanel sp = cm.PlacementTarget as StackPanel;
if (sp != null)
{
Panel parentSp = sp.Parent as Panel;
if (parentSp != null)
parentSp.Children.Remove(sp);
}
}
}
}

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 programmatically change selected tabItem Header colour from code behind

I have a program in which I have to load colours at startup.
Then I have to add a tabcontrol with tab items:
TabControl tabc = m_Executer.GetTabControl();<---- from outside
if (tabc != null)
{
TabItem tbi = new TabItem();
tbi.Header.Background = Brushes.Transparent;
tbi.Header.Content = "End manager";
tabc.Items.Add(tbi);
tabc.SelectionChanged += (sender2, args) =>
{
((TabItem)(tabc.SelectedItem)).Background = Brushes.Red;
tabc.UpdateLayout();
};
}
the idea is changing the background when the selectionchanged event is fired but that doesn't work.
The default control template for a TabItem contains two Border elements named "mainBorder" and an "innerBorder". You could change the Background of the latter one:
tabc.SelectionChanged += (sender2, args) =>
{
if(args.AddedItems != null && args.AddedItems.Count > 0)
{
TabItem ti = args.AddedItems[0] as TabItem;
if(ti != null && VisualTreeHelper.GetChildrenCount(ti) > 0)
{
Grid grid = VisualTreeHelper.GetChild(ti, 0) as Grid;
if (grid != null)
{
Border mainBorder = grid.Children[0] as Border;
if (mainBorder != null)
{
Border innerBorder = mainBorder.Child as Border;
if(innerBorder != null)
innerBorder.Background = Brushes.Red;
}
}
}
}
};
The above code works on Windows 10. The templates may differ between different versions of Windows.
If you want to change the background of the unselected TabItem you simply replace AddedItems with RemovedItems and set the Background property of the mainBorder.
You might use a textblock to change color:
TabItem tbi = new TabItem();
tbi.Header = Brushes.Transparent;
TextBlock tbk = new TextBlock() { Text="End manager" };
tbi.Header = tbk;
tabc.Items.Add(tbi);
and then change the textblock on the event
tabc.SelectionChanged += (sender2, args) =>
{
((TabItem)(tabc.SelectedItem)).Foreground = Brushes.Red;
tabc.UpdateLayout();
};
EDIT you'd better de-highlight the unselected items:
tabc.SelectionChanged += (sender2, args) =>
{
foreach (var item in tabc.Items)
{
if (item == ((TabItem)(tabc.SelectedItem)))
((TabItem)item).Foreground = Brushes.Red;
else
((TabItem)item).Foreground = Brushes.Black;
}
};
You have to set the Content to TextBlock instead of a string:
XAML:
<TabControl>
<TabControl.Items>
<TabItem >
<TabItem.Header>
<TextBlock Background="Red" Text="Foo"/>
</TabItem.Header>
</TabItem>
<TabItem Header="Bar" />
</TabControl.Items>
</TabControl>
or code behind (for whatever reason...)
TabItem tbi = new TabItem();
TextBlock headerElement = new TextBlock();
headerElement.Text = "End manager";
headerElement.Background = Brushes.Red;
tbi.Header = headerElement;
I also suggest you do take a deep dive into the MVVM pattern. In 98% of the cases it's best practice to write your UIs in XAML and bind to a ViewModel.
BTW: Your code doesn't even compile as Headeris of type object...

TabControl Focus in Popup

I'm using a Popup control with following xaml
<Popup AllowsTransparency="True" IsOpen="{Binding PopupContext.IsOpen}"
x:Name="__popup" StaysOpen="False">
<TabControl Grid.Row="1">
<TabItem Header="123"><Button>test</Button></TabItem>
</TabControl>
</Popup>
If I click Button and click outside of the popup, popup is closed normally. But if I click a TabItem and click outside parent window (if I click desktop, popup close normally), it doesn't close popup.
EDIT
I set Popup.IsOpen to true from ContextMenu.Opened event soo UIElement is focused and cant lostfocus. If UIElement.ContextMenu.Closed event fired and MouseLeaved to popup, I set Popup.IsOpen property to false. (soo if not clicked popup, it's close with ContextMenu)
private void viewModelMasa_ContextMenuOpening(MasaViewModel Sender, System.Windows.Controls.ContextMenuEventArgs args)
{
MasaView source = args.Source as MasaView;
ContextMenu menu = source.ContextMenu;
RoutedEventHandler openHandler = null;
RoutedEventHandler closeHandler = null;
this.PopupContext.Position = System.Windows.Controls.Primitives.PlacementMode.Top;
closeHandler = (sender, e) =>
{
if (!this.PopupContext.IsFocus) // Setting from Popup MouseEnter and MouseLeave event;
{
this.PopupContext.IsOpen = false;
}
menu.Closed -= closeHandler;
};
openHandler = (sender, e) =>
{
ContextMenu contextMenu = sender as ContextMenu;
if (contextMenu != null)
{
this.PopupContext.IsFocus = false;
System.Windows.Point point = new System.Windows.Point();
var pos = contextMenu.TranslatePoint(point,this.PopupContext.Parent);
this.PopupContext.Rectangle = new Rect(pos.X, pos.Y, contextMenu.ActualWidth, contextMenu.ActualHeight);
this.PopupContext.IsOpen = true;
}
menu.Opened -= openHandler;
};
menu.Opened += openHandler;
menu.Closed += closeHandler;
}

How to highlight a LongListSelector Item on the UI programmatically

I need to highlight and manipulate an item of LongListSelector on the UI for the user.
I see (this) example on code samples but couldn't understand it well.
How can I change background of the inner StackPanel which belongs to the SelectedItem and add a TextBlock into it, programmatically in code behind?
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
To make the sample you linked work with a StackPanel
private void lls_SelectionChanged(object sender, SelectionChangedEventArgs e) {
var spList = new List<StackPanel>();
GetItemsRecursive<StackPanel>(lls, ref spList);
// Selected.
if (e.AddedItems.Count > 0 && e.AddedItems[0] != null) {
foreach (var sp in spList) {
if (e.AddedItems[0].Equals(sp.DataContext)) {
sp.Background = new SolidColorBrush(Colors.Green);
sp.Children.Add(new TextBlock { Text = "Hello" });
}
}
}
// Unselected.
if (e.RemovedItems.Count > 0 && e.RemovedItems[0] != null) {
foreach (var sp in spList) {
if (e.RemovedItems[0].Equals(sp.DataContext)) {
sp.Background = (SolidColorBrush)Resources["PhoneBackgroundBrush"];
sp.Children.RemoveAt(sp.Children.Count - 1);
}
}
}
}
I am not sure whether I understood your question correctly since I am new in windows phone development. Here is the code for changing the background of stackpanel and adding textblock to it programmatically.
enter code here
// Constructor
public MainPage()
{
InitializeComponent();
// change the background of stackpanel
StackPanel st = new StackPanel();
SolidColorBrush mysolidbrush = new SolidColorBrush();
mysolidbrush.Color = Color.FromArgb(255, 100,100,10); // RGB color
st.Background = mysolidbrush;
// Adding textblock to the stackpanel
TextBlock txtblk = new TextBlock();
st.Children.Add(txtblk);
}
Best,
B

Categories