I looking for a simple example using c# to call the SetSelectionContainer method on the EnvDTE.Window class.
I would like to know what the classes should look like that I should pass to the method.
I have really searched the web now for days and could not even find anything remotely helpful.
Window window = _applicationObject.ItemOperations.NewFile(#"General\XML File", "", "");
TextSelection selection = (TextSelection) window.Document.Selection;
selection.SelectAll();
selection.Insert("<xml>some xml<xml>", (int)vsInsertFlags.vsInsertFlagsContainNewText);
object[] container = new[] {"Test1", "Test2"};
window.SetSelectionContainer(ref container);
Sets the objects that should be passed to the Properties window
whenever the window has focus. SetSelectionContainer works only on
windows created with the CreateToolWindow method. Other tool windows,
such as Solution Explorer and Task List, already have code for setting
what is displayed in the Properties window.
SetSelectionContainer
allows you to associate objects with the window so that whenever the
window has focus, the Properties window displays properties for those
objects. For example, you would use this property if you have a custom
tool window that displays a chart and you want to display properties
in the Properties window in order to change characteristics of the
chart.
If SetSelectionContainer is passed an empty Variant value, it
removes the displayed object. The object displays when the tool window
is active and the objects are available from the selection container.
Ref.
Have you downloaded the samples from here?: Automation and Extensibility for Visual Studio
From what I have discovered, you can pass simple properties, such as strings and ints in the object array parameters for this method.
It appears that the real trick to making this work is generating the notification (through ITrackSelection.OnSelectChange) that the properties have changed.
There is some working code for this here.
Related
I'm facing the following issue during setting up tooltips on a WinForms / C# desktop application (using .NET Framework version 4.5).
Application has hundreds of form elements where I would like to display a tooltip.
Current implementation as the following:
I have one toolTip object on my main form
Language file has been loaded and saved in an array
There is a method which suppose to assign the tooltip texts to the different elements accordingly by calling the SetToolTip method on the toolTip object.
E.g.
toolTip.SetToolTip(backBtn, LocalizationFile[0]);
toolTip.SetToolTip(myTextBox, LocalizationFile[1]);
It works fine, tooltips are displayed correctly.
As soon as I reach ca. 30 calls it stops working.
Calling ~30 times SetToolTip method to setup the required tooltips, cause to completely stop displaying the tooltips.
The previously worked tooltip texts are not getting display anymore.
There is no exception or any error message.
Can you please explain me why the toolTip object just stops displaying the texts after calling the SetToolTip method several times? Is there any workaround out there to apply in such cases?
EDIT-1
Following workaround works, but I'm still unsure what is the original problem.
I have created a method to call SetToolTip on the toolTip object, after calling the method, I re-create the toolTip instance using the "new" operator. That solves the issue. However as I want to disable anytime the tooltips on my application I also store all the references in a List. On that list I can iterate over to enable / disable all toolTip references according to what the user wants.
Basically there is a button to toggle the tooltips.
Do you have any idea, why this actually solves the original issue?
List<ToolTip> storeToolTipReferences = new List<ToolTip>(); //store tooltip references
//method begin called to set the tooltip on a control, store the reference of the tooltip and create a new instance
private void SetMyToolTip(Control ctrl, string toolTipText)
{
toolTip.SetToolTip(ctrl, toolTipText);
storeToolTipReferences.Add(toolTip);
toolTip = new ToolTip();
}
//called as the application loads or the user changes the language
private void SetAppLanguage(string[] LocalizationText)
{
storeToolTipReferences.ForEach(e => e.RemoveAll());
SetMyToolTip(ctrl1, LocalizationText[1]);
SetMyToolTip(ctrl2, LocalizationText[2]);
SetMyToolTip(ctrl3, LocalizationText[3]);
.....
}
//logic for tooltip enable/disable in my application
storeToolTipReferences.ForEach(t => t.Active = tooltip_control.Checked);
Thank you!
Forgive me if I get some terminology wrong. I’m going to simplify my problem a bit to target the specific piece I’m struggling with.
Scenario: I have a WPF window that I want to pass a class with properties to a WPF modal window, modify a property of the class that was passed to the modal window, and then pass the class with the update back to the original WPF modal window.
For testing/diagnostic purposes, I’m setting a value of one of the properties in the class before sending it to the modal WPF Window, and trying to bind that property to a textbox in the WPF Modal window, but I haven’t had luck. (I have shown a message box after initializing the WPF modal window showing a property of the class I manually set and it shows it, so I know the class is at least being passed to the WPF modal window, but it isn’t displaying, and I don’t know if it will pass back to the parent form if I were able to change it. )
For an example, the parent form is a basic address form, and I want to display a series of WPF modal windows to get each value so the use can type the value, press enter, and have a new window pop up for the next value. (In the real world application, many of the potential fields will be pre-populated, and if it Is, it won’t display to the user, so out of a potential 50 windows, the user may only need to see 5 to 10, but it will vary depending on what was pre-populated.)
I am displaying the WPF Modal Window with this code:
public void OpenFirstNameWindow(Person person)
{
FirstNameWindow FirstNameWindow_Child = new FirstNameWindow(person);
FirstNameWindow_Child.Owner = this;
FirstNameWindow_Child.ShowDialog();
}
For the text box I’ve tried both of these for binding
Text="{Binding FirstName}"
Text="{Binding person.FirstName}"
Neither work. I need help passing a class to, and getting it back from, a WPF modal window. Thank you for your help.
Im developing an application in C# under WPF.I want to change the status of the check box and also i need to change the text block's value of already opened window from the currently working windows operation and to update that opened window with these changes(Refresh the already opened window with some updates).
In order to control UI elements from code behind you need to assign a name to each UI element you would like to control.
As for check box decleared as
<CheckBox Name="chkA"> Checkbox A </CheckBox>
you can change its' checked state from code-behind via
chkA.IsChecked = true;
As for the diffenet window update - your Windows in WPF are just classes, part of which usually lives in *.xaml file, and another in the corresponding *.cs file.
If you declare a public method that refreshed the windows content's as you want in your second windows' class, and, when you will be creating your second window, you somehow save the reference to its' instance available in a first class (or some other logic in your application), you will be able to simply call that method from windows' 1 code to refresh the second widows appearance, as declared in a method called.
Basically, from Windows1 you call:
MySecondWindow secW = new MySecondWindow();
secW.Show();
....
secW.RefreshWithMyChages();
RefreshWithMyChages() is just a public method in your second windows' class codebehind.
All of this hold true if:
both of your windows are in the same project
you are not willing to use MVVM or other UI-patterns.
In WPF we have Window.ShowDialog() which allows showing a modal dialog box.
In WinForms there is similar functionality but it also has an overload Form.ShowDialog(IWin32Window) which allows an IWin32Window owner to be passed in. That way the new dialog is not modal, and always maintains a z-order directly above its owner.
How would I get this same functionality using WPF?
Use the Owner property on a Window.
To expand on #Jonathan.Peppers's answer:
Say you had a Window you named FooWindow, and in BarWindow.cs you wanted to create and execute an instance. You can create a modal version of FooWindow as simple as this:
new FooWindow(){ Owner = this }.ShowDialog();
That would assume you didn't need a reference to you instance, obviously, but you get the idea?
I'm having a problem understanding something about MVVM. My application relies on dialogs for certain things. The question is, where should these childwindows originate from? According to MVVM, viewmodels should contain only businesslogic and have zero actual knowledge about UI. However, what other place should I call my childwindows from, considering they're UI elements?
Doesn't this create tight coupling between elements?
Since you tagged the question with Prism, I'll suggest the way I've done it in the past using Prism. Have the IEventAggregator injected into your ViewModel, and then when you want to pop open the dialog, publish a "ShowDialogEvent" or something like that. Then, have another Module called "DialogModule" or whatever, which upon initialization subscribes to that event, and shows the dialog. Furthermore, if you want to pass data back to the original ViewModel, have the ViewModel of the dialog publish a "DialogCloseEvent" or something like that with a payload of the data you need. You can then subscribe to that event back in your main ViewModel.
See Handling Dialogs in WPF with MVVM
In the past, I have accomplished this by using Unity to resolve a custom interface that has a Show() method and a completed event. Then in the ViewModel I would call IScreen screen = container.Resolve<IScreen>(Resources.EditorWindowKey); and then just call screen.Show();.
The big advantage of this is that I can then just simply change my Unity configuration to remove the view when I'm testing my VM's.
The primary route I've been using to do this is to create a command inside your View layer. That command object accepts a parameter that is the ViewModel object that you want to display. The command then finds the appropriate ChildWindow, creates it and displays it with the parameter set as the content or however you will set it up. This way you can just bind a button's command property to that command, and its commandparameter to the object you want to show in the popup and your ViewModel objects never have to care how it's being displayed.
Prompting for user input (like saving a dirty file or something) doesn't work in this scheme. But for simple popups where you manipulate some data and then move on, this works very well.
The ViewModel sample application of the WPF Application Framework (WAF) demonstrates how to show a Modal Dialog.
I would suggest to use a controller in this scenario, say DI'ed dialogController backed up with a dialog shell. The source viewmodel(ie from where the request to open a dialog is originating) will make a call to dialogController.ShowDialog(<<ViewNameToHostInRegion>>,<<RegionName>>).
In Order to transfer the data to and from the dialog and sourceview you can use MessageBus. So essentially when you invoke the ShowDialog() you populate the messagebus, and when the close command of target View(The view hosted in Dialog shell) invoked - say in "Select" button -- Let the target view add/update the messagebus. So that source view model can work with updated data.
It has got many advantages :
1) Your source view works with dialog controller as BlackBox. ie it doesnt aware of what exactly the Dialog view is doing.
2) The view is being hosted in Dialog Shell -- so you can reuse the dialog again and again
3) Unit testing of source view is limited to test the actual functionality of the current viewmodel, and not to test the dialog view\view model.
One heads-up which I came across with this one is, while creating the test cases you may need to write testable Dialog controller which do not show the actual dialog while running the testcases in bunch. So you will need to write a TestableDialogController in which ShowDialog does nothing (Apart from deriving from IDialogController and provide blank implementation of ShowDialog().
Following is the psudeo code :
LocalMessageBus.AddMessage(<MessageKey>,<MessageActualContentAsObject>);
dialogController.ShowDialog(<TargetViewName_SayEmployeeList>);
Employee selectedEmployee = LocalMessageBus.GetMessage(<MessageKey>) as Employee;
if (selectedEmployee != null)
{
//doSomework with selected employee
}