首页 文章

使用来自powershell的wpf

提问于
浏览
0

我开始玩PowerShell了 . 目前我正在尝试加载一个显示WPF窗口的C#类,所以非常好 . 放置在窗口中的TextBlock绑定到类中的Property . (我已经在CmdLine应用程序中测试了绑定并且它工作正常)...但是当我使用add-tape从powershell加载类时,绑定将不起作用 .

我究竟做错了什么?

$a =@"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

public class TestClass : INotifyPropertyChanged
    {
        private bool _showed = false;
        private String _myString;

        public String MyString
        {
            get { return _myString; }
            set
            {
                _myString = value;
                if (!_showed)
                    ThreadStuff();
                OnPropertyChanged("MyString");
            }
        }

        public TestClass()
        {
        }

        public TestClass(String value)
        {
            _myString = value;
        }

        private void ThreadStuff()
        {
            _showed = true;
            var thread = new Thread(new ThreadStart(() =>
            {
                CreateWindow();
                System.Windows.Threading.Dispatcher.Run();
            }))
            {
                IsBackground = true
            };
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        private void CreateWindow()
        {
            var w = new Window();
            var g = new Grid();
            g.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            g.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            for (int i = 0; i < g.RowDefinitions.Count; i++)
            {
                for (int j = 0; j < g.ColumnDefinitions.Count; j++)
                {
                    var b = new Button { Content = new TextBlock { Text = i.ToString() } };
                    Grid.SetRow(b, i);
                    Grid.SetColumn(b, j);
                    g.Children.Add(b);
                }
            }

            var t = new TextBlock();
            var binding = new Binding { Source = MyString, Mode = BindingMode.OneWay };
            t.SetBinding(TextBlock.TextProperty, binding);

            (g.Children[g.Children.Count - 1] as Button).Content = t;

            w.Content = g;
            w.Show();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
"@

Add-Type -TypeDefinition $a -ReferencedAssemblies presentationcore, presentationframework, windowsbase, "System.Xaml"

$test = New-Object TestClass
$test.MyString = 'hi from powershell'

顺便说一句 . 我第一次使用PowerShell(直到现在我才使用C#) . 最后,我的目标是将Xaml文件作为视图加载,将C#文件作为视图模式加载,将它们放在一起并从powershell设置vm的属性(是的,它完全是愚蠢的,写起来更容易WPF申请...但我这样做...现在学校一天^^)

1 回答

  • 1

    你使用的是哪个版本的powershell?在Win8上的Powershell 3.0中,您的代码“适用” .

    我说“工作”因为它与我通过C#控制台应用程序运行时的工作方式相同:

    • 在设置 MyString 之前没有任何反应

    • 首次设置 MyString 时,会弹出一个GUI,右下象限包含 MyString 的值

    • 后续修改 MyString 时没有任何反应(绑定设置不正确,因此更新_72602时文本不会更新)

    如果这是您想要的行为,并且它不能正常工作,那么它可能是旧版PS的问题 .

    我怀疑你的真正问题是绑定不起作用 . 那是因为这一行:

    var binding = new Binding { Source = MyString, Mode = BindingMode.OneWay };
    

    应该

    var binding = new Binding { Source = this, Mode = BindingMode.OneWay, Path = new PropertyPath("MyString") };
    

    做出这样的改变,在C#console app和powershell中,一切似乎都很好 .

相关问题