2012-11-26 12 views
14

Yani basit kurulum, ben bir komuta bağlamak istiyorum onun Populated olayla bir autocompletebox var. BenEtkinlik bağımsız değişkenini, tetikleyicileri kullanarak bir komuta nasıl geçirebilirim?

clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity 

(Bunu yapmak için daha iyi bir ad vardır?) Kullanan

O bağlamak için büyük bir anlaşma değil, büyük bir anlaşma bağlı komutuna PopulatingEventArgs bu iddiayı geçmektir.

Peki nasıl genel olarak özellikle ve MVVM PRISM en iyi uygulamalara göre bu yaparsınız?

+0

Sorunun başlığına etiket koymayın. İyi başlıklar yazarken [bu bağlantıyı] tıklayın (http://meta.stackexchange.com/questions/10647/how-do-i-write-a-good-title);) –

cevap

24

Hiçbir yerleşik bir yolu, işte olduğu ben bunu nasıl: Biz EventArgsMouseEnter ait erişemez

<Button Content="I am a button"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="MouseEnter"> 
      <i:InvokeCommandAction Command="{Binding CommandWithNoArgs}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</Button> 

: Klasik Etkileşim tetik böyle kullanılır

Bağlanma yoluyla olay, bu yüzden onu dışarı atıyor parça değiştirmek zorunda kalacağız. O sırada da
, o yazı InvokeCommandAction olduğunu.

"Yani sadece alt sınıf ve birlikte hepimiz için bekliyordu uygun bir yöntemi geçersiz gidiyoruz" Ben yazmayı isterdim budur. Ama sınıf mühürlendi.

yüzden onun üst alt sınıfı için zorunda gidiyoruz (soyut) sınıfı: TriggerAction<DependencyObject>

en temel uygulamasıdır:

public class InteractiveCommand : TriggerAction<DependencyObject> 
{ 
    protected override void Invoke(object parameter) 
    { 
    } 
} 

Ve bu parameter senin EventArgs olduğunu!
Ama durun, o kadar basit değil, düzenli InvokeCommandAction davranışını çoğaltmak gerekir. Reflektör sayesinde
, bunu bozulamaz (ama, ben sadece tembelim resmi kaynağına bakmak gidebiliriz).

CommandParameter bağımlılık özelliği hakkında umrumda değil, biz bunu InvokeCommandAction yerine kullanırsanız, aslında her zaman EventArgs olmasını istersiniz. İşte

(WPF sadece SilverLight için EDIT bakınız) tam sınıfını geçer:

internet, alımın herhangi bir kod olduğu gibi
public class InteractiveCommand : TriggerAction<DependencyObject> 
{ 
    protected override void Invoke(object parameter) 
    { 
     if (base.AssociatedObject != null) 
     { 
      ICommand command = this.ResolveCommand(); 
      if ((command != null) && command.CanExecute(parameter)) 
      { 
       command.Execute(parameter); 
      } 
     } 
    } 

    private ICommand ResolveCommand() 
    { 
     ICommand command = null; 
     if (this.Command != null) 
     { 
      return this.Command; 
     } 
     if (base.AssociatedObject != null) 
     { 
      foreach (PropertyInfo info in base.AssociatedObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
      { 
       if (typeof(ICommand).IsAssignableFrom(info.PropertyType) && string.Equals(info.Name, this.CommandName, StringComparison.Ordinal)) 
       { 
        command = (ICommand)info.GetValue(base.AssociatedObject, null); 
       } 
      } 
     } 
     return command; 
    } 

    private string commandName; 
    public string CommandName 
    { 
     get 
     { 
      base.ReadPreamble(); 
      return this.commandName; 
     } 
     set 
     { 
      if (this.CommandName != value) 
      { 
       base.WritePreamble(); 
       this.commandName = value; 
       base.WritePostscript(); 
      } 
     } 
    } 

    #region Command 
    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Command. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty CommandProperty = 
     DependencyProperty.Register("Command", typeof(ICommand), typeof(InteractiveCommand), new UIPropertyMetadata(null)); 
    #endregion 
} 

ederim tüm sınıfa aracılığıyla okuma ve anlamaya çalışmak salık ne yapar. Sadece uygulamanıza atmayın.Şimdi

Yapabileceğimiz:

<Button Content="I am a button"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="MouseEnter"> 
      <local:InteractiveCommand Command="{Binding CommandWithEventArgs}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</Button> 

Ve arkasındaki kodu:

#region CommandWithEventArgs 
DelegateCommand<MouseEventArgs> _CommandWithEventArgs; 
/// <summary> 
/// Exposes <see cref="CommandWithEventArgs(MouseEventArgs)"/>. 
/// </summary> 
public DelegateCommand<MouseEventArgs> CommandWithEventArgs 
{ 
    get { return _CommandWithEventArgs ?? (_CommandWithEventArgs = new DelegateCommand<MouseEventArgs>(CommandWithEventArgs)); } 
} 
#endregion 
public void CommandWithEventArgs(MouseEventArgs param) 
{ 
} 

Ve bu Çekim bitti;)

DÜZENLEME: SilverLight için, bu kodu yerine kullanın:

public class InteractiveCommand : TriggerAction<DependencyObject> 
    { 
     protected override void Invoke(object parameter) 
     { 
      if (base.AssociatedObject != null) 
      { 
       ICommand command = Command; 
       if ((command != null) && command.CanExecute(parameter)) 
       { 
        command.Execute(parameter); 
       } 
      } 
     } 

     #region Command 
     public ICommand Command 
     { 
      get { return (ICommand)GetValue(CommandProperty); } 
      set { SetValue(CommandProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for Command. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty CommandProperty = 
      DependencyProperty.Register("Command", typeof(ICommand), typeof(InteractiveCommand), new UIPropertyMetadata(null)); 
     #endregion 
    } 

Ancak, lütfen tam teşekküllü WPF versiyonunu kullanmanın daha az güvenli olduğunu unutmayın (türleri kontrol etmiyor, donmuş elemanlarla çökebilir).

+0

Sadece bence çok esnek sandığımız şeyleri desteklemek için çeşitli uzantıları yazmaya giden kutu, temel. –

+0

Sadece kodunuzu denedim, kodun kendisi işe yaramadı bile fikrine sahip olmama rağmen. (daha iyi bir yerden kopyalayıp yapıştırır mı?) Temelde CommandName hiçbir zaman atanmaz ve bu nedenle ResolveCommand null değerini döndürür ve her şey bunun için çalışmaz. Ayrıca base.WritePostscript() gibi şeyler bazı küçük sorunlar vardır; bir temel sınıfta tanımlanmamış, ancak önemli değil –

+0

Tamam, lütfen kodunuzu çalıştığı kanıtlanan floş snippet'iyle değiştirin: http://pastie.org/5437478, http://pastie.org/5437483 Teşekkürler tekrar ve harika bir gün geçir! –

35

InteractiveCommand'ı denedim ve bu benim için sorunlara neden oldu. Bunun yerine Microsoft.Expression.Interactions bir başvuru ayarlayın ve benim UserControl

xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="AppointmentEditing"> 
     <ei:CallMethodAction MethodName="AppointmentEditing" TargetObject="{Binding}" /> 
    </i:EventTrigger> 
    <i:EventTrigger EventName="ShowDialog"> 
     <ei:CallMethodAction MethodName="ShowDialog" TargetObject="{Binding}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

... dahil.

Sonra halka kapsamını benim ViewModel olay işleyicileri koyup ayarlayın:

public void ShowDialog(object sender, ShowDialogEventArgs e) { 

} 

public void AppointmentEditing(object sender, AppointmentEditingEventArgs e) { 

} 

Şu ana kadar iyi çalışmak.

+1

Bu çok yararlıdır. – rajibdotnet

+5

Harika! Bu alt sınıflamadan kaçının ve kodları – isra60

+4

kodundaki olay işleyicilerinden kullanmanıza izin verin. Bana göre, bu kabul edilen yanıt olmalıdır –

İlgili konular