2010-04-27 17 views
8

Dizede tek bir argümanla özel bir etkinliğim var. Ancak, tasarımcının keyfi bir dizeye girmesine izin vermektense, tasarımcının seçenekler listesiyle birlikte bir Combobox ile sunulmasını istiyorum, seçenekler dinamiktir ve bir veritabanından bir List <> koleksiyonuna yüklenir.Özel etkinlik tasarımcısında Combobox'a veri bağlama

Sorunum nasıl bu listeye tasarımcı Combobox bağlamak için hiçbir ipucu var ve seçim faaliyetinin argüman olarak ayarlanmış olması. Görsel olarak aktivite tasarımcısının çalışması var, bu sadece bir adım.

+0

Eğer gerçekten özel etkinlik bir InArgument ziyade bir özelliği vardır istiyor musunuz? (public InArgument Arg {get; set;} vs. public dizgisi Arg {get; set;}) –

+0

@Tim, sanırım standart bir özellik de iyi olurdu. –

cevap

7

Normal olarak, bir property yerine bir InArgument aktiviteyi mal olacaktır. Bu senaryoyu kolaylaştırır: (.:

public string MyStringProperty { get; set; } 

burada ValidOptions senin ActivityDesigner sınıf bazı Koleksiyon özelliktir MyStringProperty yatan aktivite gibi bazı kamu get/set/özelliktir)

<ComboBox ItemsSource="{Binding Path=ValidOptions}" 
SelectedValue="{Binding Path=ModelItem.MyStringProperty, Mode=TwoWay}"/> 

Eğer karışıma InArgument eklerseniz olacak

sorun açılan kutudan dize değerleri doğrudan bir ModelItemInArgument<string> bekliyor tahsis edilemez olmasıdır. Bu, bağlamanızda özel bir IValueConverter kullanarak düzeltilebilir. bunu çözmek için

+0

@Tim, bu kadar uzun sürdüğü için üzgünüm, yoğun bir hafta oldu ve bunu anladığımdan emin olmak için bunu test etme şansım bile olmadı ve bunu yapmaya çalıştığımma uyuyor. Ben en kısa zamanda cevap olarak işaretlemek için ya da sizin ve toplulukların beynini daha fazla araştırmak için geri döneceğim! Teşekkürler. –

2

bir yolu UITypeEditor türemiş kendi ComboBoxEditor tanımlamaktır. Eğer etkinlik sınıfında bu combobox bağlamak ve aşağıdaki kodu kullanarak Etkinlik sınıfta bağlanabilir özelliği dekore etmek istediğiniz koleksiyonu Açığa: Eğer editvalue (ITypeDescriptorContext bağlamını değiştirmek zorunda kalacak özel comboboxEditor da

[EditorAttribute(typeof(CustomListBoxEditor), typeof(System.Drawing.Design.UITypeEditor))] 

, IServiceProvider sağlayıcısı, nesne değeri) toplama yöntemini almak ve onu combobox'a bağlamak.

4

Önceki cevaplar yardımcı oldu, ancak benim için yeterli değildi. Sonunda 2012'den Microsoft'un .Net 4.5 Geliştirici Kılavuzu'nda: Binding a custom activity property to a designer control'un müthiş bir makalesini buldum. Bu makale, özel dönüştürücü sınıfındaki küçük bir hata ve büyük bir kusur hariç, neredeyse tam cevaptı: bu teknik, ComboBox'tan bir değer kaydedecek, ancak iş akışınızı yeniden açtığınızda geri yüklemeyecek. özel etkinlik tasarımcılar için

Microsoft'un Ron Jacobs has another answer. Bir çalışma çözümü almak için ikisini birleştirdim.

ModelToObjectValueConverter Özel Tasarımcı bana IValueConverter kendi yaratmak atlamak için izin inanılmaz yararlı bir kaynak oldu. ObjectDataProvider'da, statik bir yöntem olan People.GetPeople()'u arayarak dizelerin bir listesini yüklemeyi görüyorsunuz. ComboBox öğesi kaynağı olarak bu sağlayıcı bağlanır, ancak (aşağıda) özel Faaliyet

<sap:ActivityDesigner x:Class="ActivityLibrary1.ComboBoxActivityDesigner" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation" 
    xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation" 
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation" 
    xmlns:c="clr-namespace:ActivityLibrary1"> 

    <sap:ActivityDesigner.Resources> 
     <ResourceDictionary> 
      <sapc:ModelToObjectValueConverter x:Key="ModelToObjectValueConverter" /> 
      <ObjectDataProvider x:Key="people" ObjectType="{x:Type c:People}" MethodName="GetPeople"/> 
     </ResourceDictionary> 
    </sap:ActivityDesigner.Resources> 

    <Grid> 
     <Label Content="Person" HorizontalAlignment="Left" VerticalAlignment="Top" /> 
     <ComboBox HorizontalAlignment="Left" 
        Margin="66,0,0,0" 
        VerticalAlignment="Top" 
        Width="120" 
        SelectedValue="{Binding Path=ModelItem.Person, Mode=TwoWay, Converter={StaticResource ModelToObjectValueConverter} }" 
        ItemsSource="{Binding Source={StaticResource people}}"> 
     </ComboBox> 
    </Grid> 
</sap:ActivityDesigner> 

Özel Kod Etkinliği

Not bu bir özellik yerine kullandığı üzerine Kişi özelliğine seçilen değeri bağlar ComboBox'ı daha kolay bağlayan bir InArgument'den daha fazla.

[Designer(typeof(ComboBoxActivityDesigner))] 
public class CodeActivity1 : CodeActivity 
{  
    public string Person { get; set; } 

    protected override void Execute(CodeActivityContext context) 
    { 
     // Just to demonstrate that it worked 
     MessageBox.Show(Person);  
    } 
} 

İş Akışı

Artık özel etkinlik, CodeActivity1, bir iş akışı üzerine sürüklenebilir. Bir seçim yaptığınızda, seçilen değer özellikler bölmesinde görünecektir. İş akışını kaydedin. Kapat ve tekrar aç. Önceden seçilmiş değer istenildiği gibi devam edecektir.

screenshot of custom activity designer in action

+0

Güzel örneğiniz için çok teşekkürler! –