, ben sürekli çalıştı gereken yarış durumu bir çeşit karşı gelmek gibi görünüyor. En yenisi aşağıda. Herhangi bir yardım takdir edilecektir. biri Bileşenler ve bir Üreticileri geçerli:Silverlight Combobox Veri bağlama yarış durumu
Geri ucunda iki tablo var. Her Bileşen BİR Üretici var. Hiç sıradışı, yabancı anahtar arama-ilişki değil.
Silverlight, WCF servisi aracılığıyla verilere erişmek. Bir ComboBox için olası seçimleri doldurmak için üreticilerin tam listesini almak üzere Geçerli bileşeni (görüntülemek veya düzenlemek için) ve Produ__GetAll() öğesine bir çağrı almak için Components_Get (id) öğesine çağrı yapacağım. Daha sonra ComboBox'taki SelectedItem'i Geçerli Bileşen için Üreticiye ve ComboBox'taki ItemSource'a olası Üretici listesine bağlarım. Böyle: Ben zeki var ve (Ben de Üreticileri için açmak planlanan) Bileşen küçük istemci tarafında önbelleğe alma yapana kadar
<UserControl.Resources>
<data:WebServiceDataManager x:Key="WebService" />
</UserControl.Resources>
<Grid DataContext={Binding Components.Current, mode=OneWay, Source={StaticResource WebService}}>
<ComboBox Grid.Row="2" Grid.Column="2" Style="{StaticResource ComboBoxStyle}" Margin="3"
ItemsSource="{Binding Manufacturers.All, Mode=OneWay, Source={StaticResource WebService}}"
SelectedItem="{Binding Manufacturer, Mode=TwoWay}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Name}" Style="{StaticResource DefaultTextStyle}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
Bu, uzun süre büyük çalıştı. Bileşen için önbelleğe alma özelliğini açtığımda ve bir önbellek vurulduğumda, tüm veriler doğru şekilde nesnelerde olabilirdi, ancak SelectedItem Bağlanamazdı. Bunun nedeni, çağrıların Silverlight'ta Asenkron olarak ayarlanması ve önbelleğe alma işleminin faydası olması nedeniyle, Bileşen üreticiden önce iade edilmemesidir. Böylece SelectedItem ItemsSource listesinde Components.Current.Manufacturer bulmaya çalıştığında, orada değil, çünkü bu liste hala boş çünkü Manufacturers.All henüz WCF hizmetinden yüklenmemiş. Yine, Bileşen önbelleklemeyi kapatırsam, yine çalışır, ancak YANLIŞ hisseder - tıpkı zamanlamanın çalıştığı için şanslı olduğum gibi. Doğru düzeltme IMHO, MS'in Asynch çağrılarının normal olmasıyla gerçekleşeceğini anlamak için ComboBox/ItemsControl denetimini düzeltmek içindir.
- önbelleğe eleyin veya bir kez daha maskelemek için yönüyle açın: Ama o zamana kadar ben bir ihtiyaç yo bunu düzeltmek bir yolu ... İşte ben düşündüm bazı seçenekler şunlardır gerek sorun. İyi IMHO değil, çünkü bu tekrar başarısız olur. Halı altına geri süpürmeye pek istekli değil.
- Eşitlemeyi benim için yapacak olan bir aracı nesne oluşturun (ItemsControl'ün kendisinde yapılması gerekir). Her ikisi de geldiğinde, Öğeyi ve bir ItemsList öğesini ve çıktıyı ve ItemWithItemsList özelliğini kabul eder. ComboBox'ı sonuçta elde edilen çıktıya bağlardım, böylece bir öncekinden asla bir ürün almazdı. Benim problemim bunun bir acı gibi gözükmesi ama yarış koşullarının yeniden oluşmamasından emin olmak.
Herhangi thougnts/Yorumlar?
FWIW: Ben başkalarının yararına burada çözüm yayınlayacağız.
@Joe: yanıt için çok teşekkür ederiz. UI'yi yalnızca UI iş parçacığından güncelleme ihtiyacının farkındayım. Anladığım kadarıyla, bunu SL2'de Service Reference tarafından oluşturulan kodun sizin için halledeceğini hata ayıklayıcı aracılığıyla doğruladım. yani, Manufacturers_GetAll_Asynch() yöntemini çağırdığımda, sonuçların Manufacturers_GetAll_Completed olayı aracılığıyla elde edilmesini sağlayacağım. Oluşturulan Hizmet Referans kodunun içine bakarsanız, * Tamamlanmış olay işleyicisinin UI iş parçacığından çağrılmasını sağlar. Benim sorunum bu değil, iki farklı arama (üretici listesi için ve bir üreticinin kimliğine başvuran bileşen için bir tane) yaptıktan sonra, bu sonuçların her birini tek bir ComboBox'a bağladım. Her ikisi de UI iş parçacığına bağlanırlar, sorun, listeden önce listeye ulaşmazsa seçimin yok sayılmasıdır.Ayrıca bu sorunun hala if you just set the ItemSource and the SelectedItem in the wrong order olduğunu unutmayın!
Başka Bir Güncelleme: Hala combobox yarış koşulu varken, ilginç başka bir şey keşfettim. ASLA, bu özellik için "getter" içinden bir PropertyChanged olayı oluşturmalısınız. Örnek: "SL" veri neslimdeki "Üretici" türünde "Tümü" adlı bir özelliğim var. Bu kod bir "önbellek isabet" konulu GETİRMEDİĞİ
public class ManufacturersData : DataServiceAccessbase
{
public ObservableCollection<Web.Manufacturer> All
{
get
{
if (!AllLoaded)
LoadAllManufacturersAsync();
return mAll;
}
private set
{
mAll = value;
OnPropertyChanged("All");
}
}
private void LoadAllManufacturersAsync()
{
if (!mCurrentlyLoadingAll)
{
mCurrentlyLoadingAll = true;
// check to see if this component is loaded in local Isolated Storage, if not get it from the webservice
ObservableCollection<Web.Manufacturer> all = IsoStorageManager.GetDataTransferObjectFromCache<ObservableCollection<Web.Manufacturer>>(mAllManufacturersIsoStoreFilename);
if (null != all)
{
UpdateAll(all);
mCurrentlyLoadingAll = false;
}
else
{
Web.SystemBuilderClient sbc = GetSystemBuilderClient();
sbc.Manufacturers_GetAllCompleted += new EventHandler<hookitupright.com.silverlight.data.Web.Manufacturers_GetAllCompletedEventArgs>(sbc_Manufacturers_GetAllCompleted);
sbc.Manufacturers_GetAllAsync(); ;
}
}
}
private void UpdateAll(ObservableCollection<Web.Manufacturer> all)
{
All = all;
AllLoaded = true;
}
private void sbc_Manufacturers_GetAllCompleted(object sender, hookitupright.com.silverlight.data.Web.Manufacturers_GetAllCompletedEventArgs e)
{
if (e.Error == null)
{
UpdateAll(e.Result.Records);
IsoStorageManager.CacheDataTransferObject<ObservableCollection<Web.Manufacturer>>(e.Result.Records, mAllManufacturersIsoStoreFilename);
}
else
OnWebServiceError(e.Error);
mCurrentlyLoadingAll = false;
}
}
Not olduğunu bir PropertyChanged olay üretecektir çünkü: Get In {} o yüklendikten eğer bunu böyle yükler değilse, bakar All {Get {}} yönteminden, normalde Binding System'in All {get {}} öğesini tekrar çağırmasına neden olacak olan yöntem için ... Bir ScottGu blogu geri gönderme yolundan bindable silverlight veri nesnelerini oluşturma modelini kopyaladım ve bana genel olarak iyi hizmet etti, ama bunun gibi şeyler oldukça zorlaştırıyor. Neyse ki düzeltme basittir. Umarım bu bir başkasına yardım eder.
Bu çözüm, yaygın bir çözümdür. Uzun zamandır, tüm Selector kontrollerini kapsayan daha jenerik bir çözüm arıyordum; sadece ComboBoxes değil, ve herhangi bir kontrolden miras kalmadan yapar. Bunu davranışlarla yapmanın bir yolu var. Bu önerilen çözüm UWP'de ve muhtemelen WPF'de de çalışıyor: http://stackoverflow.com/questions/36003805/uwp-silverlight-combobox-selector-itemssource-selecteditem-race-condition-solu –