I'm working on a Windows multitouch application using Surface 2.0 SDK.
I need to "clone" a control, in this specific case a ScatterViewItem, in which I've added a ElementMenu with a "CopyButton" with a Click event handler.
This is my ScatterViewItem:
<s:ScatterViewItem x:Name="PhotoPadSVI" MinWidth="296" Background="Transparent" Style="{StaticResource ScatterViewItemStyle}">......</ScatterViewItem>
And this is the code that I used and that doesn't work:
void DocumentDuplicate_Click(object sender, RoutedEventArgs e)
{
ScatterViewItem swi = PhotoPadSVI; //error is already here cause I set it as the same, but I cannot found a ".Clone()" like method
swi.Visibility = System.Windows.Visibility.Visible;
swi.ZIndex = 100;
swi.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
//sView.Items.Add(swi); cannot add to ScatterView cause swi is equal to PhotoPadSVI
}
Question: Do you know in which way could I replicate the ScatterViewItem?
You need to construct a new instance of ScatterViewItem. It should work if you set its Content the same as PhotoPadSVI's.
ScatterViewItem swi = new ScatterViewItem() { Content = PhotoPadSVI.Content };
If there is still error indicating you can't add the same item to ScatterView, you have to do from scratch, create the new ScatterViewItem's Content from code, this can be a lot more complicated if PhotoPadSVI's Content is a bunch of XAML code.
Also refer to this blog.
Related
I am making a WPF .NET 4.8 Exe application.I placed an TreeView control and made a void that is firing when window is loaded.This void adds all the sub directories and all of the files in all the sub directories and adds them to TreeView as TreeViewItem, and when they are creating their ContextMenu property is binding to a premade ContextMenu control.It also binds a click event to the MenuItems that ones ContextMenu contains.
I scripted the click event's void as RoutedEventArgs and wrote the code below (tried to access the TreeViewItem i created before).
I made some changes in my code to fix that problem but it did not work.
The code before:
void showInExplorerFolder_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("event triggered");
MenuItem menuItem = (MenuItem)sender;
//string tag = menuItem.Tag.ToString();
ContextMenu parent = (ContextMenu)menuItem.Parent;
var baseParent = parent.SourceControl;
Console.WriteLine("got success parent; ; ; ; ; ;" + menuItem.Name);
}
The code after:
void showInExplorerFolder_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("event triggered");
MenuItem menuItem = (MenuItem)sender;
//string tag = menuItem.Tag.ToString();
ContextMenu parent = (ContextMenu)menuItem.Parent;
TreeViewItem baseParent = (TreeViewItem)parent.SourceControl;
Console.WriteLine("got success parent; ; ; ; ; ;" + menuItem.Name);
}
And after theese changes i could not find any solution.
And the error code is here:
CS1061 'ContextMenu' does not contain a definition of 'SourceControl' and no inaccessible extension method 'SourceControl' is available that accepts a first argument of type 'ContextMenu' (maybe you are missing a usage or annotation reference?)
I could not find any solution.If anyone could help me, i will be thankful.
What you have done here is mixed WinForms code sample with WPF application.
To solve your problem you need to change
(TreeViewItem)parent.SourceControl; which is WinForms as SourceControl is part of ControlMenuStrip which lives in System.Windows.Forms.dll MSDN link, this is very important as WPF doesn't use that dll. It is a separate technology which uses different operating system components to render UI. For example WinForms is using GDI+ where WPF uses DirectX to render onto screen. Because of that you can't mix the 2 together as they are fundamentally different.
Solution
Use this ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as it is using WPF Controls and it is the equivalent of SourceControl. Here is a link to MSDN that will show you, it is in a different assembly.
Hope this helps
I'm writing a simple "tutorial" library that will allow developers to easily add step-by-step tutorials to their existing WPF applications. The tutorials will help first time users of the application find their way around by adding an overlay that highlights a control and explains its purpose. The end result will look something like this:
The regular application:
The overlay explaining the purpose of a control:
My question is this: What's the most reliable and unobtrusive way to inject the overlay view into the current window? The best I've come up with so far is to require the developer to add an attached property to whatever window will be hosting the overlay, and then add the necessary elements on the window's Initialized callback:
public static void IsTutorialOverlayCompatibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((Boolean)e.NewValue == true)
{
if (sender as Window != null)
{
Window window = (Window)sender;
window.Loaded += new RoutedEventHandler((o, eargs) =>
{
Grid newRootElement = new Grid();
newRootElement.Name = "HelpOverlayRoot";
if (window.Content as UIElement != null)
{
UIElement currentContent = (UIElement)window.Content;
window.Content = null;
newRootElement.Children.Add(currentContent);
newRootElement.Children.Add(new HelpOverlayControl());
window.Content = newRootElement;
}
});
}
}
}
This feels like a hack, however, and I'm not sure that there isn't some edge case where this method will break the layout of the application. In addition, it requires that the window's Content property be an instance of type UIElement.
I'd like to avoid forcing developers to change their XAML (i.e, adding a custom overlay UserControl to every window) in order to use my library. What's the best way to add this kind of functionality to an existing WPF application?
I'm working on a project and I need to embed a PowerPoint viewer in windows forms. I'm using the following activeX control: http://www.daolnwod.com/free-powerpoint-viewer-activex.html.
I activated the control to be used with the form designer's toolbox and dragged it into my form. I then edited the code in the InitializeComponent() method to the following:
this.axPowerPointViewer1 = new AxPOWERPOINTVIEWERLib.AxPowerPointViewer();
((System.ComponentModel.ISupportInitialize)(this.axPowerPointViewer1)).BeginInit();
this.axPowerPointViewer1.Enabled = true;
this.axPowerPointViewer1.Location = new System.Drawing.Point(0, 0);
this.axPowerPointViewer1.Name = "axPowerPointViewer1";
this.axPowerPointViewer1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axPowerPointViewer1.OcxState")));
this.axPowerPointViewer1.Size = new System.Drawing.Size(925, 573);
this.axPowerPointViewer1.TabIndex = 5;
//this.axPowerPointViewer1.CreateControl();
this.Controls.Add(this.axPowerPointViewer1);
((System.ComponentModel.ISupportInitialize)(this.axPowerPointViewer1)).EndInit();
And in my Forms constructor
public Form1()
{
InitializeComponent();
axPowerPointViewer1.Show();
bool loaded = axPowerPointViewer1.LoadFile(#"C:\Debug\test2.ppt"); // loaded = false
string z = axPowerPointViewer1.GetSlideCount().ToString();
}
However, when I'm opening the form nothing shows up. The code compiles but I can't see my test slide that I've been working on. I have created 2 buttons for 'Previous' and 'Next' slides but debugging gives me a slide location of 0 every time so something must be wrong and I can't seem to find it.
UPDATE
The problem has been solved. It seems I didn't call axPowerPointviewer1.InitControl(). It still has a few troubles, sometimes it won't display the first slide at startup. If things keep running smoothly I'll post an answer to this problem.
The problem is in initialising the control. In order for the control to fully function you need to call the InitControl() method so call calling the following code should make the program work:
private void Form1_Load(object sender, EventArgs e)
{
this.axPowerPointViewer1.InitControl();
}
I just found myself a new challenge:
Make a Word Processor that is in handling more like the web than plain text.
Designing a nice framework for this is what i cant wait to start with, but i do need to know what the possibilities are at the GUI side (it will probably have loads of GUI challenges).
So the basic thing that I need some sort of Control where I can make parts of my text clickable / mouse-over-able.
I'm kinda new to WPF and not sure how to do this.
Has anybody an idea how to make this?
Are there examples?
Are there already controls for this?
Thanks in advance
EDIT:
I found out some way to do it with a richtextbox:
// Create a FlowDocument to contain content for the RichTextBox.
FlowDocument myFlowDoc = new FlowDocument();
// Add paragraphs to the FlowDocument.
Hyperlink myLink = new Hyperlink();
myLink.Inlines.Add("hyperlink");
myLink.NavigateUri = new Uri("http://www.stackoverflow.com");
// Create a paragraph and add the Run and hyperlink to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add("check this link out: ");
myParagraph.Inlines.Add(myLink);
myFlowDoc.Blocks.Add(myParagraph);
// Add initial content to the RichTextBox.
richTextBox1.Document = myFlowDoc;
I now get a nice hyperlink in my textbox... except when i click it, nothing happens.
what am i missing here?
You can use the Hyperlink class. It's a FrameworkContentElement, so you can use it in a TextBlock or FlowDocument or anywhere else you can embed content.
<TextBlock>
<Run>Text</Run>
<Hyperlink NavigateUri="http://stackoverflow.com">with</Hyperlink>
<Run>some</Run>
<Hyperlink NavigateUri="http://google.com">hyperlinks</Hyperlink>
</TextBlock>
You may want to look at using a RichTextBox as part of your editor. This will host a FlowDocument, which can contain content such as Hyperlinks.
Update: There are two ways to handle clicks on the Hyperlink. One is to handle the RequestNavigate event. It is a Routed Event, so you can either attach a handler to the Hyperlink itself or you can attach one to an element higher in the tree such as the Window or the RichTextBox:
// On a specific Hyperlink
myLink.RequestNavigate +=
new RequestNavigateEventHandler(RequestNavigateHandler);
// To handle all Hyperlinks in the RichTextBox
richTextBox1.AddHandler(Hyperlink.RequestNavigateEvent,
new RequestNavigateEventHandler(RequestNavigateHandler));
The other way is to use commanding by setting the Command property on the Hyperlink to an ICommand implementation. The Executed method on the ICommand will be called when the Hyperlink is clicked.
If you want to launch a browser in the handler, you can pass the URI to Process.Start:
private void RequestNavigateHandler(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
}
Note you also need to set the following properties on your RichTextBox or the hyperlinks will be disabled and won't fire off events. Without IsReadOnly you need to Ctrl-click the hyperlinks, with IsReadOnly they fire with a regular left-click.
<RichTextBox
IsDocumentEnabled="True"
IsReadOnly="True">
The simplest way is to handle RequestNavigate event like this:
...
myLink.RequestNavigate += HandleRequestNavigate;
...
private void HandleRequestNavigate(object sender, RoutedEventArgs e)
{
var link = (Hyperlink)sender;
var uri = link.NavigateUri.ToString();
Process.Start(uri);
e.Handled = true;
}
There are some issues with starting a default browser by passing url to the Process.Start and you might want to google for a better way to implement the handler.
OK, first for context look at the Windows desktop; You can take items (folders, files) on the desktop and drag them around to different places and they "stay" where you dragged them. This seems to be a pretty useful feature to offer users so as to allow them to create their own "groupings" of items.
My question is thus:
Is there a control in .NET that approximates this behavior with a collection of items?
I'm thinking something like a listview in "LargeIcon" mode, but it allows you to drag the icons around to different places inside the control.
You can do this with a standard ListView control by implementing drag-and-drop. Here's a sample control that does this:
using System;
using System.Drawing;
using System.Windows.Forms;
public class MyListView : ListView {
private Point mItemStartPos;
private Point mMouseStartPos;
public MyListView() {
this.AllowDrop = true;
this.View = View.LargeIcon;
this.AutoArrange = false;
this.DoubleBuffered = true;
}
protected override void OnDragEnter(DragEventArgs e) {
if (e.Data.GetData(typeof(ListViewItem)) != null) e.Effect = DragDropEffects.Move;
}
protected override void OnItemDrag(ItemDragEventArgs e) {
// Start dragging
ListViewItem item = e.Item as ListViewItem;
mItemStartPos = item.Position;
mMouseStartPos = Control.MousePosition;
this.DoDragDrop(item, DragDropEffects.Move);
}
protected override void OnDragOver(DragEventArgs e) {
// Move icon
ListViewItem item = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;
if (item != null) {
Point mousePos = Control.MousePosition;
item.Position = new Point(mItemStartPos.X + mousePos.X - mMouseStartPos.X,
mItemStartPos.Y + mousePos.Y - mMouseStartPos.Y);
}
}
}
I think the closest would the ListView control, but even that is more like an explorer window. You might be able to create your own view that does what you want, but you'd need to manually persist icon locations somewhere.
If you are not opposed to using WPF, Josh Smith has created a pretty neat canvas that I am currently using for a project. It allows you to add controls and drag them around the canvas. You would have to handle what is loaded on the canvas and where on the next load of the program, but that is pretty simple.
http://www.codeproject.com/KB/WPF/DraggingElementsInCanvas.aspx
This depends on whether this is a windows application or a web browser based application. In either case you need to have some sort of container to manage the locations of controls. You can manage the position of controls inside of a container with their X and Y coordinates.
You would handle the actual movement using the drag events. So you have drag start, while dragging (you might show a place holder graphic or change the cursor), and finally a drag end (set the control's x and y to the new position). Obviously these aren't the actual event names, but a search for "how to handle drag events" should get you started.
In a web environment, I know jquery has dragging capability built in. So you might want to look at that. The one big thing you'll have to be careful of is maintaining the positions of your controls between postbacks. I'm not sure what would happen in this case.
Windows uses ListView32, an internal control with drag n' drop placeholder features, custom borders...
The icon location can be stored in a XML file, or in the application settings (by putting the XML as string and converting it to file when needed).
You can do, for example:
<icons>
<icon1>
<name>Icon1</name>
<text>My PC</text>
<imageIndex>16</imageIndex>
</icon1>
<icon2>
.....
</icon2>
.....
</icons>
Lorenzo