I am using the Tab_SelectionChanged event of TabControl in WPF. It contains 3 tab items. I have to restrict the user to navigate to other tabs i.e Settings and Schedule while work is in-progress on the home tab. While using the event i am facing an issue i.e. If i clicked on settings tab it shows me a popup "You cannot navigate while work is in progress" and when i clicked on schedule tab after clicking on settings tab it shows me the same popup twice. The reason behind this is the Settings tab remains selected.Here is my code for this:
private void tabMHPC_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TabControl tab = (TabControl)sender;
if (tab.SelectedIndex != -1)
{
if (tab.SelectedIndex != 4 && tab.SelectedIndex != 1 && tab.SelectedIndex != 0)
{
if (scanStatus == "fixing")
{
MessageBox.Show(ApplicationInfo.ApplicationName + " is still busy in fixing issues.Please let the fixation complete.", ApplicationInfo.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
homeTab.IsSelected = true;
}
else
{
MessageBox.Show(ApplicationInfo.ApplicationName + " is still busy scanning issues.Please stop it before you leave the Home tab.", ApplicationInfo.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
homeTab.IsSelected = true;
}
}
else if (tab.SelectedIndex == 0)
{
}
}
}
I want that previous tab item isSelected property gets false when i move on other tabitem.
Instead of handling the SelectionChanged event, you should data bind a property of a suitable type to the TabControl.SelectedItem property:
<TabControl SelectedItem="{Binding YourSelectedItemProperty}" ... />
When you do this, you will then be able to stop the TabItem being changed:
public YourDataType YourSelectedItemProperty
{
get { return yourSelectedItemProperty; }
set
{
if (isOkToChangeTabItem)
{
yourSelectedItemProperty = value;
NotifyPropertyChanged("YourSelectedItemProperty");
}
}
}
The final part of the solution is to set the isOkToChangeTabItem variable to true or false depending on whether it is OK for the user to change the selected TabItem or not.
Related
I need to hide the hamburger menu on certain pages but still display information in then navbar. I don’t know of any way to accomplish this.
Also, I need the navbar to stay fixed to the top of the screen but it’s getting cut off when the keyboard pops up.
How can I go about this?
FlyoutPage.ShouldShowToolbarButton method is used to determine whether to show/hide hamburger icon , and it is triggered every time when selecting pages.
We can define a bool field ,change its value when directing to specific pages.
FlyoutPage
public override bool ShouldShowToolbarButton()
{
return showIcon;
}
private bool showIcon = true;
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as FlyoutPage1FlyoutMenuItem;
if (item == null)
return;
var page = (Page)Activator.CreateInstance(item.TargetType);
page.Title = item.Title;
Detail = new NavigationPage(page);
IsPresented = false;
FlyoutPage.ListView.SelectedItem = null;
//add this logic
showIcon = (item.Id == 1) ? false : true; //only the second page do not show hamburger icon
}
Simplified version
ParentWindow.ShowDialog()
Click default/Bring Up Child Window button in ParentWindow
Click event handler for default/Bring Up Child Window button does ParentWindow.Hide()
ChildWindow.ShowDialog()
Click ChildWindow's cancel/Go Back button
ParentWindow.Visibility = Visibility.Visible
ParentWindow is nowhere to be found.
I checked, and ParentWindow returns true for IsInitialized, IsLoaded, and IsVisible. I also Alt-Tabbed my way through all my windows to look for it - it's not hiding under anything.
Why can't I see ParentWindow anywhere?
Full version
parseSettingsWindow.ShowDialog()
Click default/Bring Up Fix Selector button in parseSettingsWindow
Click event handler for default/Bring Up Fix Selector button does:
a. ParentWindow.Hide()
b. parseSettingsWindow.GoToNextWindow flag set to true (Next window is Fix Selector)
while loop does fixSelector.ShowDialog() because it's not yet loaded
Click ChildWindow's cancel/Go Back button
while loop is entered again, goes to `case "Parse Settings" section
parseSettingsWindow.Visibility = Visibility.Visible
parseSettingsWindow is nowhere to be found
I checked, and parseSettingsWindow returns true for IsInitialized, IsLoaded, and IsVisible in the Immediate Window when pausing execution on the break; line of the "Parse Settings" while loop section. I also Alt-Tabbed my way through all my windows to look for it - it's not hiding under anything.
Why can't I see parseSettingsWindow anywhere?
Main class
public static bool UserPromptedSettingsWereWrittenToModel(ref Model model, ref ActiveFixes activeFixes, ref ActiveReports activeReports)
{
var viewModel = new ViewModel();
var parseSettingsWindow = new ViewPlusViewModel.ParseSettings();
parseSettingsWindow.InitializeComponent();
var fixSelector = new ViewPlusViewModel.FixSelector(viewModel);
fixSelector.InitializeComponent();
var seeAllFixesReports = new ViewPlusViewModel.SeeAllFixesReports();
seeAllFixesReports.InitializeComponent();
parseSettingsWindow.ShowDialog();
var nextWindowToOpen = "Fix Selector";
while (parseSettingsWindow.GoToNextWindow == true && fixSelector.GoToNextWindow == false)
{
switch(nextWindowToOpen)
{
case "Fix Selector":
if (fixSelector.IsLoaded)
{
fixSelector.Visibility = Visibility.Visible;
}
else
{
fixSelector.ShowDialog();
}
nextWindowToOpen = "Parse Settings";
break;
case "Parse Settings":
parseSettingsWindow.GoToNextWindow = false;
parseSettingsWindow.Visibility = Visibility.Visible;
nextWindowToOpen = "Fix Selector";
break;
}
}
if (parseSettingsWindow.GoToNextWindow == false)
{
parseSettingsWindow.Close();
if (fixSelector.IsLoaded) fixSelector.Close();
if (seeAllFixesReports.IsLoaded) { seeAllFixesReports.Close(); }
return false;
}
parseSettingsWindow.Close();
fixSelector.Close();
if (seeAllFixesReports.IsLoaded) { seeAllFixesReports.Close(); }
return true;
}
ParseSettingsWindow.cs
private void GoToNextWindow_Click(object sender, RoutedEventArgs e)
{
this.GoToNextWindow = true;
this.Hide();
}
You can't bring a hidden .ShowDialog() window back again via Window.Visibility. You need to use .ShowDialog() on it again. In addition, any buttons given the IsCancel = True property will no longer have that functionality even when using ShowDialog() again, so presses on that button will need to be handled manually.
I am having a windows application using c#. I have created a form frmMain which loads when user logs in. There are 4 options for the user like Customer Creation, Supplier Creation, Employee Creation, User Creation
This works fine.
The issue arises with focus. When the user loads Customer user control and filling in some data and let's suppose user is somewhere on 4th control (Textbox/Combobox or any other Windows Forms input control) and suddenly he clicks on CreateUser, then CreateUser control loads, but the focus remains on the 4th control in Customer user control.
What I want is to set focus on the current user control where user left it from else if it is newly loaded set focus on default control.
Please check the code which I am using,
// this method gets called if the form was opened earlier
private void ShowOpenForm(ControlItem _item)
{
try
{
//Get item from menu
ControlItem _menuI = null;
foreach (ToolStripmenuI menuI in tsmenuWindow.DropDownItems)
{
_menuI = (ControlItem)menuI.Tag;
if (_menuI.Control.Name.ToLower() == _item.Control.Name.ToLower())
{
break;
}
_menuI = null;
}
if (_menuI != null)
{
WmenuI_ClearAllSelection();
for (int index = 0; index < PnlUserCtrl.Controls.Count; index++)
{
Control ctl = PnlUserCtrl.Controls[index];
if (ctl.Name.ToLower() == _menuI.Control.Name.ToLower())
{
ctl.Visible = true;
ctl.BringToFront();
break;
}
}
WmenuI_SetCurrentItemChecked(_menuI);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//User can navigate to opened items from menu as well
private void WindowMenuItem_Click(object sender, EventArgs e)
{
try
{
ControlItem _item = (ControlItem)((ToolStripMenuItem)sender).Tag;
WmenuI_ClearAllSelection();
for (int index = 0; index < PnlUserCtrl.Controls.Count; index++)
{
Control ctl = PnlUserCtrl.Controls[index];
if (ctl.Name.ToLower() == _item.Control.Name.ToLower())
{
ctl.Visible = true;
ctl.BringToFront();
if (ctl is BaseControl)
{
((BaseControl)ctl).SetFocus(); // This sets the focus to default textbox
}
break;
}
}
WmenuI_SetCurrentItemChecked(_item);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
But this set focus on the default textbox. Not on the control from where user moves to other user control.
It's a good practice to supply some code in your questions for the sake of getting better answers.
You can manually manipulate focus as you want using SetFocus() method. For your question I believe you can have a object of type Control then you can set it to default control you want to focus on. Then you handle all GotFocus methods of your controls and set the value of that object.
Whenever you want focus restored to last item you can call [your object].SetFocus().
This is just an idea. See if it helps.
I am Creating a sample Inventory windows form application in which if the dictionary of quantity is empty then user should not be allowed to go into sales tab.
I am using metro design and material skin mix up to design my application I have posted a code sample below which works in case of simple winform control but not working in case of metro and material design.
Code Sample
//check if selected tab is sales tab
if (tcmain.SelectedTab == tpSales)
{
//check if our cart is empty or not
if (Globals.qty.Count == 0)
{
//show error msg
var diaEmptCart = MessageBox.Show("There Are 0 Products in Cart", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
//set selected tab as purchase
tcmain.SelectedTab = tpPurchase;
}
else
{
//or show the products available in cart for sales
//populate combo box with them
cmbPro.DataSource = new BindingSource(Globals.qty, null);
//set key as display member
cmbPro.DisplayMember = "Key";
}
}
//check if selectedd tab is tab purchase
if (tcmain.SelectedTab == tpPurchase)
{
if (Globals.qty.Count == 0)
{
//if yes, setting cart empty
pbCart.Image = Image.FromFile(#"C:\Users\ThE PrOgRaMmEr\Documents\Visual Studio 2013\Projects\simpleInventory.cs.MUI\simpleInventory.cs\Resources\crt_empty.png");
}
else
{
//if not, setting cart full
pbCart.Image = Image.FromFile(#"C:\Users\ThE PrOgRaMmEr\Documents\Visual Studio 2013\Projects\simpleInventory.cs.MUI\simpleInventory.cs\Resources\crt_full.png");
}
}
You need to handle tab selecting event of the control. Try this:
private void tcmain_Selecting(object sender, TabControlCancelEventArgs e)
{
//Change whatever you want
if (tcmain.TabPages[e.TabPageIndex] == tpSales && Globals.qty.Count == 0)
e.Cancel = true;
}
But the question is why you're even displaying the tab. I'd recommend not to create tabs which aren't required.
I have a tab control in my WPF application with multiple tabs. Each tab gives access to several buttons, text boxes, drop downs. Now before moving to the next tab valid entries in each of the controls in the tab is to be checked or jumping to the next tab should not be allowed. How can this be done?
I was able to use IsEnable property to do this. But I want it like, when I click on the next tab it should, without entering the next tab, display a warning that such and such entry in the present tab is not valid.
If you adhere to the Selected event you can do something like this:
// Keep a global variable for the previous index
int prevIndex = 0;
private void tabControl_Selected(object sender, TabControlEventArgs e)
{
TabControl tc = sender as TabControl;
if (tc != null)
{
bool letSwitchHappen = validateTabControls(tc.SelectedIndex);
if (!letSwitchHappen)
{
tc.SelectedIndex = prevIndex;
}
prevIndex = tc.SelectedIndex;
}
}
Where validateTabControls is something like:
private bool validateTabControls(int tabIndex)
{
bool validEntries = false;
// Some code here to set validEntries according to the control at tabIndex
return validEntries;
}
Take a look at this example from Josh Smith.
It shows explicitly how to do this, and Josh is well-known (and respected) in the WPF world.