HelpFile contents are not opened - c#

I have an applications that install two other application which has a "Help" option. Each of these application has a common help file but the contents should be displayed based on the index selected for the application in the "Table of Contents". If i open one application, the help of that particular application should be displayed.
My code looks like this for Appl1.
private void Help_Click(Core.CommandBarButton Ctrl, ref bool CancelDefault)
{
if (System.IO.File.Exists(new PlugInConstants().HELP_FILE_Path))
{
System.Windows.Forms.Help.ShowHelp(new System.Windows.Forms.Control(),
new PlugInConstants().HELP_FILE_Path,
System.Windows.Forms.HelpNavigator.TableOfContents, "Appl1");
}
else
{
System.Windows.Forms.MessageBox.Show(m_objLanguage.ERR_HELP_NOT_FOUND.Replace
("%1", m_objGlobalConfig.HelpFilename));
}
CancelDefault = false;
}
and looks like this for Appl2
private void HelpToolStripMenuItem_Click(object sender, EventArgs e)
{
helpToolStripMenuItem.Enabled = false;
string helpFilePath;
helpFilePath = new TrayConstants().HELP_FILE_Path;
if (System.IO.File.Exists(helpFilePath))
{
System.Windows.Forms.Help.ShowHelp(new System.Windows.Forms.Control(),
helpFilePath, System.Windows.Forms.HelpNavigator.TableOfContents, "Appl2") ;
}
else
{
if (m_helpPage == null)
m_helpPage = new HelpPage();
m_helpPage.ShowDialog();
}
helpToolStripMenuItem.Enabled = true;
}
from this i can only see the Content page of common helpfile, but not the particular application help that is selected.
Now i did run Appl1 but still i can see the main MyAppbut not Appl1that is automatically selected and the contents that is displayed to right.
I am using VS 2010,C#, win forms
thanks in advance

I believe that your issue is that you are accessing the wrong value in the HelpNavigator enum. Looks like it should be Topic, not TableOfContents.
System.Windows.Forms.Help.ShowHelp(new System.Windows.Forms.Control(),
helpFilePath, System.Windows.Forms.HelpNavigator.Topic, "Appl2") ;
http://msdn.microsoft.com/en-us/library/system.windows.forms.helpnavigator.aspx

Related

How to pass a System.Drawing.Size as a parameter to a method

I am creating a my account page for my C# application. I have it setup with loads of different edit buttons for different details, i was to make it less tedious to produce and create 1 method which will change the form to the way it is needed.
Here is my code which i hope will stop the code re-use.
private void OnEditButton(string boxSelected, Size size)
{
if (doneBtn.Visible)
{
MessageBox.Show("Must edit current detail before editting a new one");
return;
}
lnametxt.Enabled = true;
lnameLink.Visible = false;
doneBtn.Visible = true;
doneBtn.Location = new Point(size);
TextBoxSelected = boxSelected;
}
The TextBoxSelected Property tells the database which column they will be changing, so this is a parameter as it will change for each edit link.
What am i trying to do? - I am trying to pass the Size as a parameter to this method. Here is the code that will call the method.
private void lnameLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
OnEditButton("lname", (495, 55));
}
at "(495, 55)" it has an error i have put the second lots of brackets to try and see if it will work with that there instead of having it on its own. Both show it has 3 parameters.
Here is the idea i am trying to go for, but without the parameters in place:
private void OnEditButton()
{
if (doneBtn.Visible)
{
MessageBox.Show("Must edit current detail before editting a new one");
return;
}
lnametxt.Enabled = true;
lnameLink.Visible = false;
doneBtn.Visible = true;
doneBtn.Location = new Point(495, 55);
TextBoxSelected = "lname";
}
if you would like any more information then please let me know and i will add it. Thank you in advance
the function OnEditButton takes two parameters, a string boxSelected and an object size of type Size.
So when you call it you have to do
OnEditButton("lname", new Size(495.0, 55.0));
You have to pass an instance of the type Size

Change App language at RunTime on-the-fly

I'm currently developing a metro app in which the user can change current language at runtime and all the custom controls that are loaded must update their text regarding to the new language. Problem is that when I change the language using the following code, the app language changes but it will only update text when I restart my app because the pages and controls that are already rendered are cached.
LocalizationManager.UICulture = new System.Globalization.CultureInfo((string)((ComboBoxItem)e.AddedItems[0]).Tag);
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = ((ComboBoxItem)e.AddedItems[0]).Tag as String;
What should I do to force updating text of all custom controls at runtime without restarting my app?
Use this:
var NewLanguage = (string)((ComboBoxItem)e.AddedItems[0]).Tag;
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = NewLanguage;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
//Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceManager.Current.DefaultContext.Reset();
and then reload your Page, using Navigate method:
if (Frame != null)
Frame.Navigate(typeof(MyPage));
In order to respond right away, you would need to reset the context of the resource manager.
For Windows 8.1:
var resourceContext = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView();
resourceContext.Reset();
You will still need to force your page to redraw itself and thus re-request the resources to get the changes to take place. For Windows 8, you can see https://timheuer.com/blog/archive/2013/03/26/howto-refresh-languages-winrt-xaml-windows-store.aspx
You can change the app's language at runtime with the help of this source code. I took help from this and manipulated my app's language settings page as follows:
In languageSettings.xaml.cs:
public partial class LanguageSettings : PhoneApplicationPage
{
public LanguageSettings()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (ChangeLanguageCombo.Items.Count == 0)
{ ChangeLanguageCombo.Items.Add(LocalizationManager.SupportedLanguages.En);
ChangeLanguageCombo.Items.Add(LocalizationManager.SupportedLanguages.Bn);
}
SelectChoice();
}
private void ButtonSaveLang_OnClick(object sender, RoutedEventArgs e)
{
//Store the Messagebox result in result variable
MessageBoxResult result = MessageBox.Show("App language will be changed. Do you want to continue?", "Apply Changes", MessageBoxButton.OKCancel);
//check if user clicked on ok
if (result == MessageBoxResult.OK)
{
var languageComboBox = ChangeLanguageCombo.SelectedItem;
LocalizationManager.ChangeAppLanguage(languageComboBox.ToString());
//Application.Current.Terminate(); I am commenting out because I don't neede to restart my app anymore.
}
else
{
SelectChoice();
}
}
private void SelectChoice()
{
//Select the saved language
string lang = LocalizationManager.GetCurrentAppLang();
if(lang == "bn-BD")
ChangeLanguageCombo.SelectedItem = ChangeLanguageCombo.Items[1];
else
{
ChangeLanguageCombo.SelectedItem = ChangeLanguageCombo.Items[0];
}
}
}
***Note: Before understanding what I did on LanguageSettings page's code behind, you must implement the codes from the link as stated earlier. And also it may be noted that I am working on windows phone 8

save and load Listbox Items locally and pass them to other pages

I am currently working on Windows Store App in c#.
Now,
I am having a list box 'Listbox1' which gets its items on a button click event from a text box 'tasks', and have selected Items delete property on other button click event.
private void add_Click(object sender, RoutedEventArgs e)
{
string t;
t = tasks.Text;
if (t != "")
{
Listbox1.Items.Add(t);
}
else
{
var a = new MessageDialog("Please Enter the Task First");
a.Commands.Add(new UICommand("Ok"));
a.ShowAsync();
}
tasks.Text = "";
}
private void del_Click(object sender, RoutedEventArgs e)
{
for (int p = 0; p < Listbox1.SelectedItems.Count; p++)
{
Listbox1.Items.Remove(Listbox1.SelectedItems[p].ToString());
p--;
}
}
Now I want to save this list into local application storage, after user complete the changes (on a button click event perhaps).
And also to send all Listbox Items to another page(s).
I am not much a coder, I design things.
Please guide me by sample or reference.
Thank you in advance :)
If you have already stored the data to local storage, you could just read it in the OnNavigatedTo override of the other page. Otherwise, use the navigation parameter: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/8cb42356-82bc-4d77-9bbc-ae186990cfd5/passing-parameters-during-navigation-in-windows-8
Edit: I am not sure whether you also need some information about local storage. This is easy: Windows.Storage.ApplicationData.Current.LocalSettings has a property called Values, which is a Dictionary you can write your settings to. Have a look at http://msdn.microsoft.com/en-us/library/windows/apps/hh700361.aspx
Edit: Try something like this code to store your list.
// Try to get the old stuff from local storage.
object oldData = null;
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
bool isFound = settings.Values.TryGetValue("List", out oldData);
// Save a list to local storage. (You cannot store the list directly, because it is not
// serialisable, so we use the detours via an array.)
List<string> newData = new List<string>(new string[] { "test", "blah", "blubb" });
settings.Values["List"] = newData.ToArray();
// Test whether the saved list contains the expected data.
Debug.Assert(!isFound || Enumerable.SequenceEqual((string[]) oldData, newData));
Note, this is only demo code for testing - it does not make real sense...
Edit: One advice: Do not persist the list in your click handlers as this will become extremely slow as the list grows. I would load and save the list in the Navigation handlers, i.e. add something like
protected override void OnNavigatedTo(NavigationEventArgs e) {
base.OnNavigatedTo(e);
if (this.ListBox1.ItemsSource == null) {
object list;
if (ApplicationData.Current.LocalSettings.Values.TryGetValue("List", out list)) {
this.ListBox1.ItemsSource = new List<string>((string[]) list);
} else {
this.ListBox1.ItemsSource = new List<string>();
}
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e) {
if (this.ListBox1.ItemsSource != null) {
ApplicationData.Current.LocalSettings.Values["List"] = this.ListBox1.ItemsSource.ToArray();
}
base.OnNavigatedFrom(e);
}
Here is very nice simple example on SQLite DataBase Use in winRT app Development. Look at it and you will know how you can store your Data on the Local Machine. I learned Basic code from this example.
http://blogs.msdn.com/b/robertgreen/archive/2012/11/13/using-sqlite-in-windows-store-apps.aspx
Now, for ease of navigation let me suggest you a flow for this portion of your app.
take one ObservableCollection<> of string and store values of
that textBox into this ObservationCollection with onClick() and then
refer that ObservableCollection<String> to the ItemsList of the
listBox.
now at the time you need to send your Data to the next page, make one parameterised constructor of next page and pass that ObservableCollection<String> as it's parameter.
Now you can access those Data in your constructor and can use as however you want.
Hope this will help..

Proper way to change language at runtime

What is the proper way to change Form language at runtime?
Setting all controls manually using recursion like this
Save language choice to file > Restart Application > Load languge
choice before InitializeComponent();
Using Form constructor to replace instance of active from (if this is even possible)
Something else
There is so much half written threads about this but none provides real answer on what is proper way to do this?
UPDATE:
To clarify my question:
Doing something like this:
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de");
this.InitializeComponent();
}
works fine and all my controls and everything else in resources get translated correctly.
And doing something like:
private void button1_Click(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
}
does nothing, Form stays in language I set up before InitializeComponent();
I believe the solution shown in Hans Passant's comment might be the only (general) solution.
Personally, I use this base class for all forms that need to be localized:
public class LocalizedForm : Form
{
/// <summary>
/// Occurs when current UI culture is changed
/// </summary>
[Browsable(true)]
[Description("Occurs when current UI culture is changed")]
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Category("Property Changed")]
public event EventHandler CultureChanged;
protected CultureInfo culture;
protected ComponentResourceManager resManager;
/// <summary>
/// Current culture of this form
/// </summary>
[Browsable(false)]
[Description("Current culture of this form")]
[EditorBrowsable(EditorBrowsableState.Never)]
public CultureInfo Culture
{
get { return this.culture; }
set
{
if (this.culture != value)
{
this.ApplyResources(this, value);
this.culture = value;
this.OnCultureChanged();
}
}
}
public LocalizedForm()
{
this.resManager = new ComponentResourceManager(this.GetType());
this.culture = CultureInfo.CurrentUICulture;
}
private void ApplyResources(Control parent, CultureInfo culture)
{
this.resManager.ApplyResources(parent, parent.Name, culture);
foreach (Control ctl in parent.Controls)
{
this.ApplyResources(ctl, culture);
}
}
protected void OnCultureChanged()
{
var temp = this.CultureChanged;
if (temp != null)
temp(this, EventArgs.Empty);
}
}
Then instead of directly changing Thread.CurrentThread.CurrentUICulture, I use this property in static manager class to change UI culture:
public static CultureInfo GlobalUICulture
{
get { return Thread.CurrentThread.CurrentUICulture; }
set
{
if (GlobalUICulture.Equals(value) == false)
{
foreach (var form in Application.OpenForms.OfType<LocalizedForm>())
{
form.Culture = value;
}
Thread.CurrentThread.CurrentUICulture = value;
}
}
}
I have found another way:
Move initialization form code in a private method like below:
private void FormInitialize() {/*Your code here*/}
In the form constructor use it like this:
public Form1()
{
InitializeComponent();
FormInitialize();
}
And from Button, menuItem or other call method like this:
private void ChangeCultureToFrench_Click(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr");
this.Controls.Clear();
this.InitializeComponent();
FormInitialize();
}
I hope this helps ;-)
I've discovered this kind of approach a few minutes ago. Just quick and simple restart of the main form. Meybe it will help to someone. Event is created inside the form on my own, called when user selects the language from menu but after the selected culture's name is saved into the settings. Culture names are then loaded from that settings. Works exactly as I need and looks like proper solution.
static class Program
{
private static bool doNotExit = true;
private static FormMain fm;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
while(doNotExit)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(Properties.Settings.Default.language);//
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.language);//
doNotExit = false;
fm = new FormMain();
fm.lanugageChangedEvent += new EventHandler(main_LanugageChangedEvent);
Application.Run(fm);
}
}
static void main_LanugageChangedEvent(object sender, EventArgs e)
{
doNotExit = true;
fm.Close();
}
}
In reference to your ColumnHeader .NET framework bug, I also discovered this bug recently and posted a question about it (to which I haven't received any responses). I was able to fix the problem by hardcoding the changes for the ColumnHeaders. For example:
resources.ApplyResources(_myHeader, "_myHeader", culture);
You basically just replace the call to .Name with a literal string of the name. I have tested this and it works. Unfortunately this means it won't fit as part of the code you use to change all of the controls. You will have to add a line for each ColumnHeader object you need to change. If you have a listview with a variable number of columns, that could get tricky. Another option is to create localized resource files. I assume you probably already have them for stuff like message box text and other strings. Then you can add an entry in your resource file like "columnHeader_myHeader" and set the appropriate language text for each language. Finally, you can manually change the text to your column headers by using:
_myHeader.Text = myResourceFileName.columnHeader_myHeader;
This will select the appropriate language based on the current thread culture.
Hans was correct in that there doesn't seem to be a foolproof "proper" way to perform localization in .NET, though there are a variety of tools you can use. For something like a job application, even though it is probably already too late for this advice, my suggestion would be to learn as many different methods as you can for localization, learn the pros and cons, and then just pick a system and be able to argue why you believe it is the "proper" choice. They are probably more concerned with your logic and reasoning and demonstration of prior experience than they are with the actual method.
Hope this would help anyone, I found it best for me cause i needed to change buttons location according the lang (browse on the right or left of the search box and labels next to text fields).
save a public var on the main that will hold the lang.
created a class which handles the visual part
created xml files that will hold any language data and more (in my xml tag name=object name).
sent that class's constructor the form (to save and work with)
connect to that current xml file
From main form call whenever you want to initialView (part of the view class) and change lang (and more) anytime (just connect to the right xml file):
public void initialView()
{
//Set rightToLeft values
initialIndent(mainForm);
//set visual text values
initialTxt();
}
private void initialTxt()
{
// Are there any more controls under mainObj (Form1)?
Boolean endOfElemsUnderPnl = false;
// The current Control im working on
Object curObj = mainForm;
do
{
// MenuStrip needs to be handled separately
if (typeof(MenuStrip).ToString().Equals(curObj.GetType().ToString()))
{
foreach (ToolStripMenuItem miBase in ((MenuStrip)(curObj)).Items)
{
miBase.Text = mainForm.dbCon.getData(miBase.Name.ToString());
foreach (ToolStripMenuItem miInnerNode in miBase.DropDownItems)
{
miInnerNode.Text = mainForm.dbCon.getData(miInnerNode.Name.ToString());
}
}
}
// Any other Control i have on the form
else
{
((Control)(curObj)).Text = mainForm.dbCon.getData(((Control)(curObj)).Name.ToString());
}
curObj = mainForm.GetNextControl(((Control)(curObj)), true);
// Are there any more controls under mainObj?
if (null == curObj)
{
endOfElemsUnderPnl = true;
}
} while (!endOfElemsUnderPnl);
}
private void initialIndent(frmMyFileManager parent)
{
if (parent.Language.Equals("Hebrew"))
{
parent.RightToLeft = RightToLeft.Yes;
}
else if (parent.Language.Equals("English"))
{
parent.RightToLeft = RightToLeft.No;
}
else
{
parent.RightToLeft = RightToLeft.No;
}
}
And this is an example of how easy it is for my at runtime:
private void selectLanguageToolStripMenuItem_Click(object sender, EventArgs e)
{
DialogResult res = MessageBox.Show(this, "click yes for english and no for hebrew", "Select language", MessageBoxButtons.YesNoCancel);
if (DialogResult.Yes == res)
{
Language = "English";
}
else if (DialogResult.No == res)
{
Language = "Hebrew";
}
dbCon = new CDBConnector("****\\lang" + Language + ".xml");
view.initialView();
}

HowTo Disable WebBrowser 'Click Sound' in your app only

The 'click sound' in question is actually a system wide preference, so I only want it to be disabled when my application has focus and then re-enable when the application closes/loses focus.
Originally, I wanted to ask this question here on stackoverflow, but I was not yet in the beta. So, after googling for the answer and finding only a little bit of information on it I came up with the following and decided to post it here now that I'm in the beta.
using System;
using Microsoft.Win32;
namespace HowTo
{
class WebClickSound
{
/// <summary>
/// Enables or disables the web browser navigating click sound.
/// </summary>
public static bool Enabled
{
get
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Current");
string keyValue = (string)key.GetValue(null);
return String.IsNullOrEmpty(keyValue) == false && keyValue != "\"\"";
}
set
{
string keyValue;
if (value)
{
keyValue = "%SystemRoot%\\Media\\";
if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor > 0)
{
// XP
keyValue += "Windows XP Start.wav";
}
else if (Environment.OSVersion.Version.Major == 6)
{
// Vista
keyValue += "Windows Navigation Start.wav";
}
else
{
// Don't know the file name so I won't be able to re-enable it
return;
}
}
else
{
keyValue = "\"\"";
}
// Open and set the key that points to the file
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
key.SetValue(null, keyValue, RegistryValueKind.ExpandString);
isEnabled = value;
}
}
}
}
Then in the main form we use the above code in these 3 events:
Activated
Deactivated
FormClosing
private void Form1_Activated(object sender, EventArgs e)
{
// Disable the sound when the program has focus
WebClickSound.Enabled = false;
}
private void Form1_Deactivate(object sender, EventArgs e)
{
// Enable the sound when the program is out of focus
WebClickSound.Enabled = true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// Enable the sound on app exit
WebClickSound.Enabled = true;
}
The one problem I see currently is if the program crashes they won't have the click sound until they re-launch my application, but they wouldn't know to do that.
What do you guys think? Is this a good solution? What improvements can be made?
const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
const int SET_FEATURE_ON_PROCESS = 0x00000002;
[DllImport("urlmon.dll")]
[PreserveSig]
[return: MarshalAs(UnmanagedType.Error)]
static extern int CoInternetSetFeatureEnabled(int FeatureEntry,
[MarshalAs(UnmanagedType.U4)] int dwFlags,
bool fEnable);
static void DisableClickSounds()
{
CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS,
SET_FEATURE_ON_PROCESS,
true);
}
I've noticed that if you use WebBrowser.Document.Write rather than WebBrowser.DocumentText then the click sound doesn't happen.
So instead of this:
webBrowser1.DocumentText = "<h1>Hello, world!</h1>";
try this:
webBrowser1.Document.OpenNew(true);
webBrowser1.Document.Write("<h1>Hello, world!</h1>");
You disable it by changing Internet Explorer registry value of navigating sound to "NULL":
Registry.SetValue("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\Explorer\\Navigating\\.Current","","NULL");
And enable it by changing Internet Explorer registry value of navigating sound to "C:\Windows\Media\Cityscape\Windows Navigation Start.wav":
Registry.SetValue("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\Explorer\\Navigating\\.Current","","C:\Windows\Media\Cityscape\Windows Navigation Start.wav");
Definitely feels like a hack, but having done some research on this a long time ago and not finding any other solutions, probably your best bet.
Better yet would be designing your application so it doesn't require many annoying page reloads.. for example, if you're refreshing an iframe to check for updates on the server, use XMLHttpRequest instead. (Can you tell that I was dealing with this problem back in the days before the term "AJAX" was coined?)
If you want to use replacing Windows Registry, use this:
// backup value
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Current");
string BACKUP_keyValue = (string)key.GetValue(null);
// write nothing
key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
key.SetValue(null, "", RegistryValueKind.ExpandString);
// do navigation ...
// write backup key
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
key.SetValue(null, BACKUP_keyValue, RegistryValueKind.ExpandString);

Categories

Resources