Is there a way to convert ContentControl to this - c#

MessageBoxEx
I trying to implement XAML into CS. It succeeded but only 1 thing I can't solve and that is:
Convert this to ContentControl.
object parent = this;
MessageBoxEx.SetParentWindow(this);
The parent windows must be set otherwise I get a null reference.
Can somebody help me out?
Found the solution
public void InitMessageBox()
{
// Create the ElementHost control for hosting the
// WPF UserControl.
ContentControl host = new ContentControl();
host.DataContext = this;
//host.Dock = DockStyle.Fill;
// Create the WPF UserControl.
MessageBoxEx uc =
new MessageBoxEx();
// Assign the WPF UserControl to the ElementHost control's
// Child property.
//host.Parent = this;
//host.Child = uc;
// Add the ElementHost control to the form's
// collection of child controls.
//this.Controls.Add(host);
// p = (ContentControl) this;
MessageBoxEx.SetParentWindow(host);
MessageBoxEx.SetMessageForeground(Colors.White);
MessageBoxEx.SetMessageBackground(Colors.Black);
MessageBoxEx.SetButtonBackground(MessageBoxEx.ColorFromString("#333333"));
MessageBoxEx.SetButtonTemplateName("AefCustomButton");
MessageBoxEx.SetMaxFormWidth(600);
MessageBoxEx.SetErrorDelegate(new ErrorMsgDelegate());
// if you want to make the MessageBoxEx silent when you use icons, uncomment the next line
//MessageBoxEx.SetAsSilent(true);
}

I have not done this but you must follow a special procedure to use a WPF control with Windows Forms. Please see this link: Use WPF controls in Windows Forms apps

I've some code found:
public void InitMessageBox()
{
// Create the ElementHost control for hosting the
// WPF UserControl.
ElementHost host = new ElementHost();
host.Dock = DockStyle.Fill;
// Create the WPF UserControl.
MsgBoxEx.MessageBoxEx uc =
new MsgBoxEx.MessageBoxEx();
// Assign the WPF UserControl to the ElementHost control's
// Child property.
host.Parent = this;
host.Child = uc; // Error
// Add the ElementHost control to the form's
// collection of child controls.
this.Controls.Add(host); // host = error
// p = (ContentControl) this;
MessageBoxEx.SetParentWindow(uc);
MessageBoxEx.SetMessageForeground(Colors.White);
MessageBoxEx.SetMessageBackground(Colors.Black);
MessageBoxEx.SetButtonBackground(MessageBoxEx.ColorFromString("#333333"));
MessageBoxEx.SetButtonTemplateName("AefCustomButton");
MessageBoxEx.SetMaxFormWidth(600);
MessageBoxEx.SetErrorDelegate(new ErrorMsgDelegate());
// if you want to make the MessageBoxEx silent when you use icons, uncomment the next line
//MessageBoxEx.SetAsSilent(true);
}
This code I have from internet but does not work

Related

Displaying user control in parent form panel

The first line is able to clear the panel but doesnt seem to show the usercontrol in the panel in the parent form.
panel1.Parent.Controls.Clear();
if (panel1.Parent == null)
return;
messagessent uc = new messagessent();
uc.Dock = DockStyle.Fill;
panel1.Parent.Controls.Add(uc);
Why you use panel1.Parent? In this way, you remove all controls not from the panel itself, but from the parent control on which this panel is located.
This action removes the panel itself. And, accordingly, the panel does not have a parent now. The Parent property becomes null.
I suppose you need to write like this:
panel1.Controls.Clear();
messagessent uc = new messagessent();
uc.Dock = DockStyle.Fill;
panel1.Controls.Add(uc);

Container UserControl - Handle and Modify Added Controls

I'm trying to create a custom container as UserControl.
My Goal: I want to be able to drag controls inside the designer and handle incoming controls inside the code of my usercontrol.
Example: I place my container somewhere and then add a button. In this momemt I want my usercontrol to automatically adjust the width and position of this button. Thats the point where Im stuck.
My code:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ContactList : UserControl
{
public ContactList()
{
InitializeComponent();
}
private void ContactList_ControlAdded(object sender, ControlEventArgs e)
{
e.Control.Width = 200; // Nothing happens
e.Control.Height = 100; // Nothing happens
MessageBox.Show("Test"); // Firing when adding a control
}
}
The MessageBox is working well. The set width and height is ignored.
The question is just "why?".
EDIT
I've just noticed, when placing the button and recompiling with F6 the button gets resized to 200x100. Why isnt this working when placing?
I mean... the FlowLayoutPanel handles added controls right when you place it. Thats the exact behaviour im looking for.
Using OnControlAdded
To fix your code, when you drop a control on container and you want to set some properties in OnControlAdded you should set properties using BeginInvoke, this way the size of control will change but the size handles don't update. Then to update the designer, you should notify the designer about changing size of the control, using IComponentChangeService.OnComponentChanged.
Following code executes only when you add a control to the container. After that, it respects to the size which you set for the control using size grab handles. It's suitable for initialization at design-time.
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
if (this.IsHandleCreated)
{
base.BeginInvoke(new Action(() =>
{
e.Control.Size = new Size(100, 100);
var svc = this.GetService(typeof(IComponentChangeService))
as IComponentChangeService;
if (svc != null)
svc.OnComponentChanged(e.Control,
TypeDescriptor.GetProperties(e.Control)["Size"], null, null);
}));
}
}

Windows form ElementHost hosting a wpf menu usercontrol that opens windows forms childs on the windows forms host

i know this may look a Little confusing, but i have an application built in Windows forms, that has a menu and almost 20 options in a treeview that opens Windows forms child on the main form, but it looks awful, so i wanted to build a usercontrol in wpf that has the options and storyboards, but my problem is that i cant find a way to open the child forms on the main menu when i click the corresponding option in the wpf usercontrol
do someone knows is this is possible?
ElementHost host = new ElementHost();
UserControl2 uc1 = new UserControl2();
host.Child = uc1;
host.Dock = DockStyle.Fill;
this.Controls.Add(host);
i did it with this logic
public FormParent parent { get; set; }
private void button_Click(object sender, RoutedEventArgs e)
{
var source = (HwndSource)PresentationSource.FromDependencyObject(button);
var host = (System.Windows.Forms.Integration.ElementHost)System.Windows.Forms.Control.FromChildHandle(source.Handle);
var form = (System.Windows.Forms.Form)host.TopLevelControl;
FormChild newMDIChild = new FormChild();
newMDIChild.MdiParent = form;
newMDIChild.Show();

AdornerLayer.GetAdornerLayer() return NULL for all controls in a Panel

I'm facing the fact that i cannot understand Well how AdornerLayer is added for UIElements.
I have such a situation:
I have a WPF Form which is built with 3 controls:
A Grid on which are 1 Button and 1 TextBox.
In my System, when I click to open this Form, all 3 elements have AdornerLayer not null .
var controls = _frameworkElementProvider.GetUIElements(Content);
var controlsWithAddorner = new List<FrameworkElement>();
foreach (var control in controls) {
var adornerLayer = AdornerLayer.GetAdornerLayer(control);
if (adornerLayer != null) {
controlsWithAddorner.Add(control);
}
}
The collection controlsWithAddorner contains all my 3 controls.
The method GetUIElements(FrameworkElement parent) returns an IEnumerable<FrameworkElement> in which are all controls within a Panel.
I have such a functionality:
Refresh Form Designer. Which recreates the xaml for that Form.
After that Refresh is done, I check the list of controls for AdornerLayer. For all controls the AdornerLayer is null.
The problem is here, I cannot understand where AdornerLayer (s) are lost?
Should I take care To add them forr each UIElement when I Refresh the Designer of the Form?
Please advice me with some suggestions.
Thank you!
EDIT:
I'll show all the solution if other will encounter such problems :)
The mission is: When there is a SelectedControl in designer, keep it selected even a RefreshDesigner is done.
RefreshDesigner functionality recreates the xaml for the whole form.
// Refresh the Designer
private void RefreshDesigner() {
Content = _xamlProvider.ParseXaml(_xaml.ToString());
//Here was the Problem. All visual child elements of the Content wa not updated after xaml recreation.
//By including that call -> solved the problem
Content.UpdateLayout();
}
Firstly: The xaml of the Form is Updated by using the ParseXaml() method from XamlProvider
// in XamlProvider class
public Panel ParseXaml(string xaml) {
var regex = new Regex("<Grid ");
const int first = 1;
xaml = Regex.Replace(xaml, #"xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""", string.Empty);
xaml = Regex.Replace(xaml, #"xml:space=""preserve""", string.Empty);
//...
xaml = Regex.Replace(xaml, "<BindingGroup .*/>", string.Empty);
var content = (Panel)XamlReader.Parse(xaml);
return content;
}
Secondly: Content.UpdateLayout();
Ensures that all visual child elements of this element are properly updated for layout.
MSDN Official source
After that, All elements have AdornelLayer not Null and I'm able to set the Adorner Border for preciosly selected control in designer.
After the Form is Refreshed, call Content.UpdateLayout(); to Ensures that all visual child elements of the Content were properly updated for layout. MSDN official

PopUp Window WPF Form Custom Control Content

I have a form done in WPF which has a custom control already on it called RateView. This custom control has 4 textboxes (which are all working as they should be). It also contains a button.
I have a second custom control called Extended Margin Info, which also has a XAML Form which will just show output data only.
How can I by clicking the button on the custom control called Rateview bring up the XAML canvas onto my Main window of the extendedmargin info XAML, in the same position everytime? Rateview control exists 5 times on the main window therfore there will be 5 buttons that when clicked, will need to output the popup of ExtendedMargin Info to the main screen in the same position each time with the content of extendedmargin info.
Your button, when clicked, should call a Command which updates a Property of some ViewModel that exposes the ViewModel of the current ExtendedMarginInfo you want to display. Then you can bind this property to the Content Property of a ContentControl in the target view. You can select the View you want the Control to display by using the ContentControl.ContentTemplateSelector property.
I guess you want show one popup and change it's content placing in it different controls.
At 1st create your custom control:
balloon = new LogEntryInfoBalloon();
balloon.SetMainWindow(this);
balloon.DataContext = vm.NotificationViewModel;
Then create Popup control (System.Windows.Controls.Primitives):
localPop = new Popup();
localPop.AllowsTransparency = true;
localPop.Placement = PlacementMode.AbsolutePoint;
localPop.StaysOpen = true;
localPop.PlacementTarget = this;
localPop.Child = balloon;
Placement target points to MainWindow.
Define timer that will close(hide) balloon:
localPopTimer = new Timer(new TimerCallback(CloseLocalPopup));
Close func:
private void CloseLocalPopup(object args)
{
var act = new Action(() =>
{
localPop.IsOpen = false;
});
Dispatcher.BeginInvoke(act, null);
}
Show balloon code looks like this:
private void ShowNotifyBaloon(NotifyBaloonViewModel vm)
{
var act = new Action(() =>
{
localPop.IsOpen = true;
localPopTimer.Change(4000, Timeout.Infinite);
});
Dispatcher.BeginInvoke(act, null);
}

Categories

Resources