|
Thanks a lot, Christian. Magic that I didn't know about: "[InternetShortcut]". I Googled for that and found out how to extend your code to get the icon out of the linkUrl. Here is my code combining your suggestion with the extension:
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=" + linkUrl);
writer.WriteLine("IconFile=" + linkUrl);
writer.WriteLine("IconIndex=0");
writer.Flush(); The next thing to do is to programmatically add links to the Quick Launch bar. For that you have to get the path to the Quick Launch folder. I do that in the following function, which is like yours, except it generates a path to the Quick Launch folder and also establishes the icon:
private void ShortcutToQuickLaunchFolder(string linkName, string linkUrl)
{
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string quickLaunchFolder = appData + @"\Microsoft\Internet Explorer\Quick Launch";
using (StreamWriter writer = new StreamWriter(quickLaunchFolder + "\\" + linkName + ".url"))
{
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=" + linkUrl);
writer.WriteLine("IconFile=" + linkUrl);
writer.WriteLine("IconIndex=0");
writer.Flush();
}
} Everything works beautifully! Hope this is useful for other people.
|
|
|
|
|
I discovered a big limitation that .lnk files do not have. The URL File Format apparently does not support command line parameters, so if a program has several modes of operation, you're stuck. I tried specifying a batch file to invoke the program, where the batch file contains the full path of the executable plus a command line parameter and it didn't work.
|
|
|
|
|
Hi fjparisIII,
I am new to creating setup...and just a beginner. Could you please tell me where should i write this function "ShortcutToQuickLaunchFolder(string linkName, string linkUrl).
Thank you very much
|
|
|
|
|
I scratch-built my own setup program in two days, just using core .NET API's. I don't use an MSI file. I figured writing my own setup program from core .NET API's would be faster than learning how to link into the MSI infrastructure and API. I don't even know if there is an MSI API. You probably know more than I do if you can even ask this question.
|
|
|
|
|
FWIW, writing a shortcut file directly is poor practice IMO, and could
lead to tears in the future.
IShellLink is the proper way to go (has been since Windows 95). Here's an
example of using it from a .NET app:
Creating and Modifying Shortcuts[^]
If that's too much, then the second best option would be to use the Windows Script Host.
Here's one example:
How to create Windows shortcut (C#)[^]
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: writing a shortcut file directly is poor practice IMO, and could
lead to tears in the future.
Was never proposing that.
Mark Salsbery wrote: IShellLink is the proper way to go
If you saw my original MFC code that I quoted, you'd have seen that that's what I originally did, and what I was asking was how hard it would be to wrap that COM code into something that could be called from WPF? Would I have to go to unmanaged code? I don't want to do that.
|
|
|
|
|
Mark Salsbery wrote: If that's too much, then the second best option would be to use the Windows Script Host.
Here's one example:
How to create Windows shortcut (C#)[^]
This looks like the way to go. Don't know anything about Windows Script Host, but the reference is just a recipe I could probably follow.
|
|
|
|
|
Hi,
Recently I'm trying to learn WPF, and I've stumbled across a problem, I can solve it, but I'm not happy with the result code, so maybe someone could help me to polish it a bit.
Let's say, I have class XManager, that manages classes X, also, it has reference to currently active X instance, each class X has it's own Text property, I want to do a two way binding between textbox and this text property.
It looks like this:
class XManager
{
private X activeX;
public X ActiveX
{
get { return activeX; }
}
}
class X : INotifyPropertyChanged
{
public string Text { get; set; }
public void PutSomeTextProgramatically(string someText)
{
Text += someText;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Text"));
}
}
Now, I do have a manager accessible from XAML:
<Windows.Resources>
<local:XManager x:Key="xManager"/>
</Windows.Resources>
My binding to it looks like this:
<TextBox Name="someBox">
<TextBox.Text>
<Binding Mode="TwoWay" Source="{StaticResource xManager}" Path="ActiveX.Text" />
</TextBox.Text>
</TextBox>
Such code won't work properly, because we've binded to XManager's "ActiveX.Text", but we never change it, so workaroun I did was to add do my manager such code:
void XSession_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Text")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("ActiveSession.Text"));
}
}
Now it will work, but I find such code a bit ugly, I'd like to bind "directly" to PropertyChange event inside XSession, not to some sort of a wrapper. Is this possible, or maybe I don't see something obvious?
|
|
|
|
|
The Path "ActiveX.Text" should be "Text"
Change to: <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path=".Text" />
BTW: Any reason you're not setting the DataContext on the TextBoxes Parent container to an instance of the xManager class? Then you don't need a resource. Your application may need to follow the pattern you've described, just want me sure you knew there are other ways.
Also, xManager is not public. I've run into problems when the classes exposed on the UI are not public. Not all cases, just mentioning I've hit issues.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Karl Shifflett wrote: The Path "ActiveX.Text" should be "Text"
Change to: <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path=".Text" />
I've actually did, just forgot to include this change in my post , actually, I've manage to make it work without this wrapper thing on XManager. If I would set Path="Text", I'd have to include this wrapper, so XManager would have to catch it's activeX text change and repost it, but now for some reason I am able to set two way binding without this wrapper, just binding to Path="ActiveX.Text" (it did not work earlier heh).
Karl Shifflett wrote: BTW: Any reason you're not setting the DataContext on the TextBoxes Parent container to an instance of the xManager class? Then you don't need a resource. Your application may need to follow the pattern you've described, just want me sure you knew there are other ways.
This may be a newbie question, but how I do that? If I won't add the XManager to window resources, but only create it's instance in the code part, I don't see any of binding to it, I was actually thinking is it possible to bind to an instance of a class that was created in code, but I gave up and just used resources.
|
|
|
|
|
DataContext is KEY to programming in WPF. Without a full understand of this property you will struggle with WPF when infact it's super powerful and simple (once you grasp how it works.)
Strongly recommend you read, print, study, this post: http://msdn.microsoft.com/en-us/library/ms752347.aspx[^]
It's some VERY good Microsoft documentation on Data Binding.
Another fantasic WPF Data Binding resource is: http://bea.stollnitz.com/blog/[^]
modified 27-Feb-21 21:01pm.
|
|
|
|
|
I do get your point, I just don't see why I can't use XManager as a resource, and how else I can refer to it's instance, if I won't declare it this way? I'm using Data contexts with success while referring to resources, using
DataContext="{Binding Source={StaticResource resourceKeyName}}"
|
|
|
|
|
Not sure I understand the question or what is not working as expected.
I do have another consideration.
When you create xManager as a resource, it is actually instantiating an instance of the xManager. So... that instance will be available to your UI but not the code-behind unless you reference the instance using resource lookup.
Hope this helps.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
I think we need a 'reset', cause I'm a bit lost in our discussion as well .
So:
1. Not, I do not have any problems with code not working, I'm just referring to your statement, that I could throw out XManager from resources.
2. Let's consider such code (pseudo-xaml):
<Window>
<Window.Resources>
<local:XManager x:Key="xManager"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource xManager}}">
...
<TextBox Text="{Binding Mode=TwoWay, Path=ActiveSession.InputText}" />
</Grid>
</Window>
This is a simplified situation of what I have right now in my code. Referring to your post, I could throw out xManager from resources -> this implies that I create instance of the XManager in the code, fe. in the Window ctor; my question is then, how I could refer to such an instance in XAML in DataContext, and if it's not easy / possible, what's the advantage of throwing out xManager from resources.
Also, inside a code I did something like this:
XManager xMgr;
public MainWindow()
{
InitializeComponent();
xMgr = (XManager)FindResource("xManager");
So basically, I do have a straightforward access to this instance from a code.
|
|
|
|
|
Loose the resource and all references to it.
Loose the Grid DataContext XAML.
In code (ctor or Loaded Event) set Window DataContext.
this.DataContext = new xManager;
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Working great, I think I've tried to over-Xaml heh . I can see how this can be useful, altough not in every situation, but still, works fine.
Thank you very much for the support.
|
|
|
|
|
|
Make sure that the chart data source implements change notification. (INotifyCollectionChanged)
That way when you make the chart visible and the collection its bound gets new data it will notify the Chart and it will display.
In WPF or Silverlight you can use the System.Collections.ObjectModel.ObservableCollection(Of T)
modified 27-Feb-21 21:01pm.
|
|
|
|
|
|
You can leave the DependencyProperty.
In order to help, I'll need you to post the code and XAML here.
If you can shrink it down to a small repro of the issue, that would be very helpful.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
If I add an Expander to my Window then when I click the expander in the design window or go into the XAML for the expander the expander will expand. However if I create my own template for the expander as below (it will expand on mouse over), then it does not expand as it did before. How can I get this to happen?
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border BorderBrush="Black"
BorderThickness="1"
CornerRadius="3">
<Border.Background>
<LinearGradientBrush StartPoint="0.5,0"
EndPoint="0.5,1">
<GradientStop Color="#22FFFFFF" Offset="0" />
<GradientStop Color="#EEFFFFFF" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<HeaderedContentControl>
<HeaderedContentControl.Header>
<TextBlock Text="{TemplateBinding Header}"
Margin="3" />
</HeaderedContentControl.Header>
<ContentPresenter x:Name="myContent"
Visibility="Collapsed" />
</HeaderedContentControl>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="myContent" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
|
|
|
|
|
The template you write, replaces the one that was there before. you need to get the original template, and add your bits, without removing the bits that are now missing, as the old template is replaced with this one. I believe Expression will help you find the default XAML for the built in controls, or you can google for it
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
In addition to Christian's reply..
Sample templates for many WPF controls are available in the SDK.
Here's the expander template:
Expander ControlTemplate Example[^]
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Ok, having looked at this I realise I did not quite get it right. But it would appear that when I have the Expander selected in Visual Studio the IsExpanded property is set to true which causes it to expand. This behaviour does not seem to exist in Blend. Here I have to right click and select Expand Expander. What is causing this behaviour?
|
|
|
|
|
Hi guys,
I'm about re-planning a larger LOB application (an older version, created as a 2-tier solution is already existing and running for a couple of years). The plan is to go from 2-tier to 3-tier. We are not about to reuse code, so in this regard I'm totally free! Ah yes, it's not a web-application (so no ASP.NET or Silverlight)... Merely Winforms/WPF...
What I am thinking about is whether or not to not make all service directly accessible via a WCF-Service (per class) or going to implement a single Service for communication (call it "CommService" which can send and receive serialized objects) to handle data exchange.
The application relies on several different entities (so I definetly have to implement a couple of WCF-Services when using the one-service-per-entity approach).
What would be the best approach in your opinion?
Greetings,
Stephan Eberle
hawke@deltacity.org
|
|
|
|
|