简体   繁体   中英

WPF XAML Hello World from scratch, with delegates

I want to get a XAML specified interface on the screen so I can learn WPF. But I do not want to start from a visual studio project which has all the wire-up already done. I wan't the c# "hello world" equavalent of drawing a window specified in a xaml file on the screen from the "main()" function.

So how do I wire-up a XAML file to an object and draw it on the screen from a console app ? Please wire-up a simple event as well. Say a "hello world" button (specified in xaml), that when pressed makes the console print "hello world". I'd prefer to see the delegate function in the following ways.

  1. The logic as inline c# in XAML.
  2. The logic specified in the same file as the "main()" method, as a free function (edit : oh wait c# doesn't have free functions, well a delegate of some sort that isn't code behind).
  3. The logic as a member function of an object, where I believe the object to be the codebehind of the XAML (assuming ofcourse this way of mapping between xaml and c# objects is possible).

Additionally : This answer shows the ui runloop taking over the main thread, is there any sugar to create a new thread for the app so it doesn't block the callee ?

If your wondering why I am asking this question, or why I want to learn WPF this way. I want to trigger ad-hoc UI elements from within a plugin that has no other means of displaying information.


For those that find this question too vague, here is an example of xaml

<Canvas xmlns="http://schemas.microsoft.com/client/2007"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextBlock>Hello World!</TextBlock>
</Canvas>

The main app in this question is a console c# app, the XAML file represents a form with a single button, pressing the button prints "hello world" to the console. And I want to see the different ways of wiring up the button to my code, I do not understand how I could be clearer.

At the risk of being told this is not what you asked, but since it's not clear:

class WpfSample
{
    [STAThread]
    public static void Main()
    {
        var window = new Window()
        {
            Title = "WPF",
            Width = 640,
            Height = 480
        };

        var grid = new Grid();

        var button = new Button()
        {
            Content = "Click Me",
            Width = 100,
            Height = 50,

        };

        grid.Children.Add(button);
        window.Content = grid;

        button.Click += (s, e) =>
        {
            MessageBox.Show("You clicked me");
        };

        window.ShowDialog();

    }
}

That being said, if you want plugins for your WPF application, doing it like this (all with code) is not the way to go.

We define controls en such in plugins without the need for hooking it all up in code, we use MEF for that.

Update To load the UI from some XAML you stored somewhere, you can use a ValueConverter

public class StringToXamlValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string xaml;
        if (value != null && !String.IsNullOrWhiteSpace(value.ToString))
        {
            xaml = value.ToString();
        }
        else
        {
            xaml = Settings.Default.DefaultLayoutView;
        }

        var root = XamlReader.Parse(xaml);
        return root;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

You'd then set the content of some element like this:

<ContentControl Content="{Binding Layout.View, Converter={StaticResource StringToXamlConverter}}"/>

To cut straight to the point:

I want to trigger ad-hoc UI elements from within a plugin that has no other means of displaying information.

There is absolutely no need to draw a window from scratch, instead you can use the ShowDialog() method on the Window object:

var myWindow = new Window();
myWindow.ShowDialog();

of course you can programmatically add whatever controls you want to that window, or you could have it already defined as XAML somewhere which you then re-hydrate as a window.

Having said that, ideally the host of your plugin should provide you with a container that you can add content to (or provide a dialog service that you've hand rolled), rather then you having to forcibly show stuff directly from the plugin.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM