Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从另一个xaml更改xaml按钮的属性_C#_Xaml_Silverlight_Mvvm - Fatal编程技术网

C# 从另一个xaml更改xaml按钮的属性

C# 从另一个xaml更改xaml按钮的属性,c#,xaml,silverlight,mvvm,C#,Xaml,Silverlight,Mvvm,我是Silverlight和MVVM的新手,我正在尝试更改按钮。我在应用程序中启用了一个xaml与另一个xaml的 我试图创建一个类,但我不确定我是否正确使用它 using System.ComponentModel; namespace Reporting.Models { public class DataSourceValidation : INotifyPropertyChanged { private bool _isSaveEnabled; public bool

我是Silverlight和MVVM的新手,我正在尝试更改
按钮。我在应用程序中启用了一个xaml与另一个xaml的

我试图创建一个类,但我不确定我是否正确使用它

using System.ComponentModel;

namespace Reporting.Models
{
public class DataSourceValidation : INotifyPropertyChanged
{
    private bool _isSaveEnabled;

    public bool IsSaveEnabled
    {
        get
        {
            return _isSaveEnabled;
        }
        set
        {
            _isSaveEnabled = value;
            RaisedPropertyChanged("IsSaveEnabled");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisedPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}
}

如果能给我一个解释和例子,我将不胜感激。我一直在寻找,但它没有完全与我点击如何将控件绑定到一个模型,然后从另一个xaml.cs更改该值。。。只要我用正确的方式思考这个问题


如果我需要提供更多信息,请询问。谢谢您的时间。

如果您只是不想快速完成(没有好的解决方案),那么您可以使用静态属性实现这一点:

ExampleA.xaml.cs
中创建以下属性:

public static ExampleA CurrentInstance { get; private set; }
EventAggregator.Instance.Publish(new EnableButtonMessage());
ExampleA
的构造函数中(我假设类的名称是
ExampleA
):

然后在您的
示例b
LostFocus
方法中:

if (ExampleA.CurrentInstance != null)
{
     var button = ExampleA.CurrentInstance.FindName("OKButton") as Button;
     if (button != null)
     {
         button.IsEnabled = true;
     }
}
另一方面,我不知道您的类是如何构造的,这些XAML文件是如何关联的,但是一个好的通用解决方案是使用以下模式:

我在这里使用的是
Caliburn.Micro
MVVM框架中的
EventAggregator
类的一个稍加修改的版本:

namespace Caliburn.Micro
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    /// <summary>
    ///   A marker interface for classes that subscribe to messages.
    /// </summary>
    public interface IHandle { }

    /// <summary>
    ///   Denotes a class which can handle a particular type of message.
    /// </summary>
    /// <typeparam name = "TMessage">The type of message to handle.</typeparam>
    public interface IHandle<TMessage> : IHandle
    {
        /// <summary>
        ///   Handles the message.
        /// </summary>
        /// <param name = "message">The message.</param>
        void Handle(TMessage message);
    }

    /// <summary>
    ///   Enables loosely-coupled publication of and subscription to events.
    /// </summary>
    public interface IEventAggregator
    {
        /// <summary>
        ///   Gets or sets the default publication thread marshaller.
        /// </summary>
        /// <value>
        ///   The default publication thread marshaller.
        /// </value>
        Action<System.Action> PublicationThreadMarshaller { get; set; }

        /// <summary>
        ///   Subscribes an instance to all events declared through implementations of <see cref = "IHandle{T}" />
        /// </summary>
        /// <param name = "instance">The instance to subscribe for event publication.</param>
        void Subscribe(object instance);

        /// <summary>
        ///   Unsubscribes the instance from all events.
        /// </summary>
        /// <param name = "instance">The instance to unsubscribe.</param>
        void Unsubscribe(object instance);

        /// <summary>
        ///   Publishes a message.
        /// </summary>
        /// <param name = "message">The message instance.</param>
        /// <remarks>
        ///   Uses the default thread marshaller during publication.
        /// </remarks>
        void Publish(object message);

        /// <summary>
        ///   Publishes a message.
        /// </summary>
        /// <param name = "message">The message instance.</param>
        /// <param name = "marshal">Allows the publisher to provide a custom thread marshaller for the message publication.</param>
        void Publish(object message, Action<System.Action> marshal);
    }

    /// <summary>
    ///   Enables loosely-coupled publication of and subscription to events.
    /// </summary>
    public class EventAggregator : IEventAggregator
    {

        /// <summary>
        /// The singleton instance.
        /// </summary>
        public static EventAggregator Instance = new EventAggregator();

        /// <summary>
        ///   The default thread marshaller used for publication;
        /// </summary>
        public static Action<System.Action> DefaultPublicationThreadMarshaller = action => action();

        readonly List<Handler> handlers = new List<Handler>();

        /// <summary>
        ///   Initializes a new instance of the <see cref = "EventAggregator" /> class.
        /// </summary>
        public EventAggregator()
        {
            PublicationThreadMarshaller = DefaultPublicationThreadMarshaller;
        }

        /// <summary>
        ///   Gets or sets the default publication thread marshaller.
        /// </summary>
        /// <value>
        ///   The default publication thread marshaller.
        /// </value>
        public Action<System.Action> PublicationThreadMarshaller { get; set; }

        /// <summary>
        ///   Subscribes an instance to all events declared through implementations of <see cref = "IHandle{T}" />
        /// </summary>
        /// <param name = "instance">The instance to subscribe for event publication.</param>
        public virtual void Subscribe(object instance)
        {
            lock (handlers)
            {
                if (handlers.Any(x => x.Matches(instance)))
                    return;

                handlers.Add(new Handler(instance));
            }
        }

        /// <summary>
        ///   Unsubscribes the instance from all events.
        /// </summary>
        /// <param name = "instance">The instance to unsubscribe.</param>
        public virtual void Unsubscribe(object instance)
        {
            lock (handlers)
            {
                var found = handlers.FirstOrDefault(x => x.Matches(instance));

                if (found != null)
                    handlers.Remove(found);
            }
        }

        /// <summary>
        ///   Publishes a message.
        /// </summary>
        /// <param name = "message">The message instance.</param>
        /// <remarks>
        ///   Does not marshall the the publication to any special thread by default.
        /// </remarks>
        public virtual void Publish(object message)
        {
            Publish(message, PublicationThreadMarshaller);
        }

        /// <summary>
        ///   Publishes a message.
        /// </summary>
        /// <param name = "message">The message instance.</param>
        /// <param name = "marshal">Allows the publisher to provide a custom thread marshaller for the message publication.</param>
        public virtual void Publish(object message, Action<System.Action> marshal)
        {
            Handler[] toNotify;
            lock (handlers)
                toNotify = handlers.ToArray();

            marshal(() =>
            {
                var messageType = message.GetType();

                var dead = toNotify
                    .Where(handler => !handler.Handle(messageType, message))
                    .ToList();

                if (dead.Any())
                {
                    lock (handlers)
                    {
                        foreach (var handler in dead)
                        {
                            handlers.Remove(handler);
                        }
                    }
                }
            });
        }

        protected class Handler
        {
            readonly WeakReference reference;
            readonly Dictionary<Type, MethodInfo> supportedHandlers = new Dictionary<Type, MethodInfo>();

            public Handler(object handler)
            {
                reference = new WeakReference(handler);

                var interfaces = handler.GetType().GetInterfaces()
                    .Where(x => typeof(IHandle).IsAssignableFrom(x) && x.IsGenericType);

                foreach (var @interface in interfaces)
                {
                    var type = @interface.GetGenericArguments()[0];
                    var method = @interface.GetMethod("Handle");
                    supportedHandlers[type] = method;
                }
            }

            public bool Matches(object instance)
            {
                return reference.Target == instance;
            }

            public bool Handle(Type messageType, object message)
            {
                var target = reference.Target;
                if (target == null)
                    return false;

                foreach (var pair in supportedHandlers)
                {
                    if (pair.Key.IsAssignableFrom(messageType))
                    {
                        pair.Value.Invoke(target, new[] { message });
                        return true;
                    }
                }

                return true;
            }
        }
    }
}
然后,您的
ExampleA
类需要实现
IHandle
接口(在构造函数中,您需要订阅该类正在接收某种消息,并且在接收到注册类型的实际消息时执行
Handle
方法,然后在其中启用按钮):

这是
EventAggregator
模式的一个简单实现,然后您可以使用if在应用程序内部的任何实体之间进行全局消息传递。这是一个强大的模式,当与MVVM一起使用时,可以使您的生活更加轻松

public class EnableButtonMessage
{
}
public sealed class ExampleA : UserControl, IHandle<EnableButtonMessage>
{
    ...
    public ExampleA()
    {
        this.InitializeComponent();
        EventAggregator.Instance.Subscribe(this);
    }
    ...
    public void Handle(EnableButtonMessage message)
    {
        this.OKButton.IsEnabled = true;
    }
    ...
}
EventAggregator.Instance.Publish(new EnableButtonMessage());