C# 从另一个xaml更改xaml按钮的属性
我是Silverlight和MVVM的新手,我正在尝试更改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
按钮。我在应用程序中启用了一个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());