MVVM ile WPF'deki gibi bir görünüm modelindeki bir komut nasıl bir düğmeye bağlanabilir?WinForms komutlarına bağlanma
cevap
Daha önce Button
ve MenuItem
nesnelerin Tag
özelliğine ICommand
nesneleri ekledim. (Örn Button
, MenuItem
)
ben bunu doğrudan sanmıyorum ama nasıl komutu çağırmak için düğmenin tıklama işleyicisi kullanmaya ne dersiniz? WPF kadar temiz değil ama yine de ayrılığını alıyorsun.
Ben WPF yanı sıra WinForms kullanabilirsiniz INotifyPropertyChanged uygulanması tavsiye ederim. Bazı ek bilgi için bir giriş ve here için bkz. here.
You denetimleri sınıflara deneyin hatta daha kolay bir yaşam için
private void button1_Click(object sender, EventArgs e)
{
ICommand command = ((Control)(sender)).Tag as ICommand;
if (command != null)
{
command.Execute();
}
}
: Ben, örnek döküm ve eğer yapabilirsem çalıştırabilirsiniz eğer
Sonra ben sadece görmek WAF Windows Forms Adapter'u ilginç bulabilir. Windows Forms uygulamasında Model-View-ViewModel (MVVM) Kalıbının nasıl uygulanacağını gösterir. Adaptör uygulaması, Windows Forms'taki eksik Komutu desteği için bir çözüm sağlar. Aynı şeyin yapılabilir acaba ve Bu
denetimin etkin durumunu değiştirme (Application.Idle olayı üzerine) kayıtlı komutları sorgular ve veri bağlama kullanan basit bir CommandManager'da yazma sona erdi
Şu anda kullanıyorum kodu:
Ayrıcapublic partial class Form1 : Form
{
private CommandManager commandManager;
public ICommand CommandA { get; set; }
public ICommand CommandB { get; set; }
public bool condition;
public Form1()
{
InitializeComponent();
commandManager = new CommandManager();
CommandA = new DelegateCommand("Command 1", OnTrue, OnExecute);
CommandB = new DelegateCommand("Command 2", OnFalse, OnExecute);
commandManager.Bind(CommandA, button1);
commandManager.Bind(CommandB, button2);
commandManager.Bind(CommandA, command1ToolStripMenuItem);
commandManager.Bind(CommandB, command2ToolStripMenuItem);
}
private bool OnFalse()
{
return !condition;
}
private bool OnTrue()
{
return condition;
}
private void OnExecute()
{
condition = !condition;
}
}
kod gerekirse, ben blogg:
public class CommandManager: Component
{
private IList<ICommand> Commands { get; set; }
private IList<ICommandBinder> Binders { get; set; }
public CommandManager()
{
Commands = new List<ICommand>();
Binders = new List<ICommandBinder>
{
new ControlBinder(),
new MenuItemCommandBinder()
};
Application.Idle += UpdateCommandState;
}
private void UpdateCommandState(object sender, EventArgs e)
{
Commands.Do(c => c.Enabled);
}
public CommandManager Bind(ICommand command, IComponent component)
{
if (!Commands.Contains(command))
Commands.Add(command);
FindBinder(component).Bind(command, component);
return this;
}
protected ICommandBinder FindBinder(IComponent component)
{
var binder = GetBinderFor(component);
if (binder == null)
throw new Exception(string.Format("No binding found for component of type {0}", component.GetType().Name));
return binder;
}
private ICommandBinder GetBinderFor(IComponent component)
{
var type = component.GetType();
while (type != null)
{
var binder = Binders.FirstOrDefault(x => x.SourceType == type);
if (binder != null)
return binder;
type = type.BaseType;
}
return null;
}
protected override void Dispose(bool disposing)
{
if (disposing)
Application.Idle -= UpdateCommandState;
base.Dispose(disposing);
}
}
public static class Extensions
{
public static void Do<T>(this IEnumerable<T> @this, Func<T, object> lambda)
{
foreach (var item in @this)
lambda(item);
}
}
public abstract class CommandBinder<T> : ICommandBinder where T: IComponent
{
public Type SourceType
{
get { return typeof (T); }
}
public void Bind(ICommand command, object source)
{
Bind(command, (T) source);
}
protected abstract void Bind(ICommand command, T source);
}
public class ControlBinder: CommandBinder<Control>
{
protected override void Bind(ICommand command, Control source)
{
source.DataBindings.Add("Enabled", command, "Enabled");
source.DataBindings.Add("Text", command, "Name");
source.Click += (o, e) => command.Execute();
}
}
public class MenuItemCommandBinder : CommandBinder<ToolStripItem>
{
protected override void Bind(ICommand command, ToolStripItem source)
{
source.Text = command.Name;
source.Enabled = command.Enabled;
source.Click += (o, e) => command.Execute();
command.PropertyChanged += (o, e) => source.Enabled = command.Enabled;
}
}
ve bu nasıl kullanılacağını bir xmaple olduğunu edition here
çözümünüz gayet iyi çalışıyor ve diyalog bileşenlerini çok daha kolay ve anlaşılabilir hale getiriyor :-). çok teşekkürler! – rhe1980
iyi çalışıyor ve hoşunuza gitti! –
Neden "DataSourceUpdateMode", "DataBindings.Add (..)" yöntemini kullanarak 'Application.Idle' olayı kullandığınızı açıklar mısınız? –
Bir komutun, ButtonBase
'dan miras alınan herhangi bir sınıfa bağlanmasına izin veren bir genel komut bağlama sınıfı oluşturabilirsiniz.
public class CommandBinding<T> where T : ButtonBase
{
private T _invoker;
private ICommand _command;
public CommandBinding(T invoker, ICommand command)
{
_invoker = invoker;
_command = command;
_invoker.Enabled = _command.CanExecute(null);
_invoker.Click += delegate { _command.Execute(null); };
_command.CanExecuteChanged += delegate { _invoker.Enabled = _command.CanExecute(null); };
}
}
sonra aşağıdaki kodu kullanarak ayarlanabilir bağlama komut:
: öylesine doğal bir kaç uyarılar vardır size bir başlangıç vermek benim uygulanmasıCommandBinding<Button> cmdBinding =
new CommandBinding<Button>(btnCut, CutCommand);
Bu sadece çıplak kemikleri
- Örnek, WPF
ICommand
arabiriminin kullanılmasını varsayar; bu nedenle, komut deseninin kendi uygulamanızın olması durumunda değiştirilmeniz gerekebilir. - Gönderilen parametreler boş başvurular için kontrol edilmelidir.
- Daha somut bir uygulama, bellek sızıntılarını önlemek için olay işleyicilerini kaldırma yöntemine sahip olmalıdır.
jenerik kısıt da Click
olayı ve komutlar hemen her Kontrole bağlı anlamına gelir Enabled
özellik sunar Control
için değiştirilebilir.
button1.Click += (s, e) => new MyCommand().Execute();
Eğer tasarımcı kullanarak denetime komutu bağlamak istiyorsanız Windows Formları MVVM nasıl kullanılacağını göstermek nerede bu demo uygulamasını kontrol edin:
https://bitbucket.org/lbras/mvvmforms
sahip olduğunuz tek kod kod arkasında yazmak için görünüm modeli örneğinin oluşturulmasıdır.
- 1. winForms + DataGridBir Listeye bağlanma <T>
- 2. WinForms
- 3. VsVim'deki anahtarlar Visual Studio komutlarına nasıl eşlenir?
- 4. C# WinForms
- 5. winforms akordeon
- 6. Komut satırı komutlarına bir dizi tuş vuruşunu eşleme
- 7. Sayfayı Google E-Tablolar için API Komut Dosyası komutlarına dönüştürün?
- 8. Winforms: CheckedListBox'un Checkbox öğesini
- 9. WinataErrorInfo winforms içinde
- 10. Winforms javascript setTimeout eşdeğeri
- 11. Üçgenlere bağlanma ağacı
- 12. Yuvarlak kenarlar (WinForms)
- 13. açısal iki yönlü bağlanma?
- 14. Uzak redis sunucusuna bağlanma
- 15. Team Foundation Server'a bağlanma
- 16. Birden çok tabloya bağlanma
- 17. WinForms kullanmadan imleç döndürme
- 18. DevExpress'e Bağlanma StockSeries2D Grafiği
- 19. Winforms PropertyGrid - özellikler düzenlenemez
- 20. url'yi kullanarak postgresql'e bağlanma
- 21. PHP AIM TOC'ye bağlanma
- 22. WinForms veya WPF
- 23. Linux'dan erişim veritabanına bağlanma
- 24. S3'ye bağlanma
- 25. İki değere bağlanma
- 26. Mac: IOBluetoothCihazına otomatik bağlanma
- 27. Gp'ye bağlanma WPF.ColumnSpan
- 28. SQLAlchemy kullanarak veritabanına bağlanma
- 29. MVC'de bir SelectList'e bağlanma
- 30. WinForms Uygulamasına "Yardım" Entegrasyonu
Evet, aslında şu an şu an yapıyorum - bunu bağlayıcı bir şekilde yapmanın makul bir yolu olup olmadığını merak ediyorum. –