2010-08-19 19 views
9

Benim asıl soru, bir denetim için birden çok kaynağa sahip olduğumuz (bir datagrid içinde bir combobox) (veya hem datacontext hem de itemssource sahip) olay yerinde bağlama durumu hakkında. O zaman bağlamanın hangi kaynağı kullanacağını nasıl bilebiliriz? (bunu açıklamak için herhangi bir sözdizimi)ÖğelerSource vs DataContext bağlama durumunda

Bir datagrid öğesinin bir itemssource = "Oyuncular Listesi" datacontext = "Manager" ve bir tür sütun olarak bir combobox sahip olduğunu varsayalım. Ayrıca, her oyuncunun bir koleksiyon türü olan bir Envanter mülküne sahip olduğunu varsayarız. Sonra DataGrid.Columns içeride

:

  1. (bağlanma için) her bir sütunun akım kaynağı bir oyuncu (bu ben şimdiye kadar bunu anlamak nasıl) 'dir. Sadece oynatıcının mülküne "yönetici" veri mülkünün mülkiyetine bağlanabiliriz. "Yönetici" nin mülkiyetine bağlamanın hiçbir yolu yoktur. Doğrumuyum?
  2. Ancak, combobox sütunlarına geçersek, combobox'ın itemssource = 'player' envanteri 'olmasına izin verdiğimi varsayalım, sonra comboboxItem için geçerli kaynak envanterde her öğe olacaktır. Ve eğer bağlayıcıyı kullanırsam, sadece bu eşyaların mülküne bağlanabilir. Ancak, bazen de, özellikle seçilen Değer ve SelectedItem özelliklerinin, combobox'ın özelliklerinin içindeki özelliğine bağlayabileceğimiz kodu görüyorum. Biraz kafam karıştı bana yardım edebilir misin?

size

cevap

8

bir ItemsControl (ItemsControl den ComboBox devralır ve DataGrid çok benzer davranır) 'dir düşünmek anahtar kontrolünü teşekkür ederim.

Bir ItemsControl tip IEnumerable ait ItemsSource özelliğine sahiptir. Ayrıca, ItemTemplate özelliğine sahiptir. yapacağı şey, ürünündeki her öğe için bir kopyasını ItemTemplate oluşturun. ItemTemplate'un DataContext her bir öğesi ItemsSource içinde olacaktır. ComboBox senin durumunda

, DataGrid 'ın sütunun DataContext sizin Player nesne olacak. ComboBox'un ItemSource ürününü Player envanterine bağlarsanız, her öğeyi ComboBox listenizden alırsınız.
Dikkat edilmesi gereken nokta, ComboBox'un DataContext'un kendisinin değişmemiş olmasıdır. Hala Player nesnesidir. Sizin için, ComboBox için belirtirseniz,envanterinde bulunan öğelere göre DataContext olacaktır.

+0

SelectedValue, SelectedItem için, eğer bağlayıcıysak, o zaman combobox'ın datacontext'ine (combobox'ın itemsource'undaki her bir öğenin özelliği değil) özelliğine bağlanır. Bu nedenle, Combobox'ın şimdiki değeri olan SelectedValuePath, DisplayMemberPath öğesinin veri katmanı olan Player'ın özelliğidir: temelde bağlayıcı olmadığından, değere atamak için İşaretleme Sözdizimini kullanmayız. Bu yüzden, öğenin mülkünün adını, itemsource'unda (datacontext'in mülkiyeti değil) atayabiliriz. Haklı mıyım – Tai

6

Gerçekten çok basit.

DataContext, öğelerin aynı özelliklerine karşılık gelir. Uzatılmıyor ve dinamik değil. DataContext, şu anda ebeveynin içinde bulunan çocuk özellikleri için geçerlidir.

Ancak ItemsSource dinamiktir. Kaynakla birlikte uzar. İşte bir gud örneğidir.

Bu örnek bir xaml. İşte

<UserControl x:Class="SilverlightApplication" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="400"> 

<Grid x:Name="LayoutRoot" Background="White"> 
    <Grid.Resources>   
     <DataTemplate x:Key="template2"> 
      <StackPanel Orientation="Horizontal"> 
       <Image x:Name="img1" Source="{Binding Image}"></Image> 
       <TextBlock x:Name="data2" Text="{Binding Data}"></TextBlock> 
      </StackPanel> 
     </DataTemplate> 
    </Grid.Resources> 
    <StackPanel> 
     <StackPanel x:Name="DataContextStack" Orientation="Vertical"> 
      <TextBlock x:Name="data1" Text="{Binding Text1}"></TextBlock> 
      <TextBlock x:Name="data2" Text="{Binding Text2}"></TextBlock> 
     </StackPanel> 
     <ListBox x:Name="lst2" ItemTemplate="{StaticResource template2}"></ListBox> 
    </StackPanel> 
</Grid> 

arkasında kodudur.
namespace SilverlightApplication 
{ 
    public partial class MainPage : UserControl 
{ 
    public MainPage() 
    { 
     InitializeComponent(); 
     loadLists(); 
    } 

    private void loadLists() 
    { 
     ObservableCollection<Temp2> tColl = new ObservableCollection<Temp2>();    

     Temp1 t1 = new Temp1(); 
     t1.Text1 = "DataContext1"; 
     t1.Text2 = "DataContext2";    

     tColl.Add(new Temp2() { Image = "", Data = "Item1" }); 
     tColl.Add(new Temp2() { Image = "", Data = "Item2" }); 


     DataContextStack.DataContext = t1; 
     lst2.ItemsSource = tColl;    
    } 
} 

public class Temp1 
{ 
    public string Text1 { get; set; } 
    public string Text2 { get; set; } 



} 

public class Temp2 
{ 
    public string Image { get; set; } 
    public string Data { get; set; } 
} 
} 

Gördüğünüz gibi

, DataContext StackPanel var ve Metin ise tek özelliği başvurmak TextBlocks için de geçerlidir.

ItemsSource, Textblock öğesinin Resim ve Metin özelliğinin Kaynağını ifade ederken, listenin içindeki öğeler de GözlemlenebilirKoleksiyon ile birlikte genişletilebilir. Ya da sizin için daha da basitleştirebilirsiniz.

DataContext - Değer, tasarıma göre ayarlanır. Öğeler Kaynak - Değer, mantık temelinde ayarlanır.

Bu yardımcı olur umarım.

Sorunuz yanıtlanırsa, bunu yanıt olarak işaretle.

+0

Merhaba Aswin, yardımlarınız için teşekkür ederim. Örneğinizi anlıyorum ama sormak istediklerim, aynı denetim için hem item kaynak hem de veri kontekstine sahip olma durumudur (içindeki combobox sütunu ile datagrid durumu). Sanırım Stephan'ın cevabı, karışıklığımın çoğunu temizliyor. cevabınız da yararlıdır. Teşekkürler – Tai

+0

Aynı şey. Örnekte söylediğim gibi 2 metin bloğu içeren bir liste kutunuz varsa. Verileri bağlamak için DataContext'i kullanabilirsiniz. Çocukları olarak farklı kontrolleri olması durumunda, ItemsSource kullanmak en iyi seçenek olacaktır. Her ikisi de farklı senaryolarda kullanılan DataBinding fenomeni. –

İlgili konular