Próbuję utworzyć niestandardową kontrolę użytkownika, z podobną funkcjonalnością jak DataGrid (ale DataGrid nie jest tu odpowiednią opcją).Niestandardowa kontrola z kaskadowym DataContext do elementów potomnych w kolekcji
Co chciałbym osiągnąć coś takiego:
<my:CustomList ItemsSource="{Binding Items}">
<my:CustomList.Columns>
<my:Column Width="60" Binding="{Binding MyCustomProperty}" />
</my:CustomList.Columns>
</my:CustomList>
gdzie przedmioty będzie pochodzić z ViewModel (na przykład) tak:
public ObservableCollection<Item> Items { get; set; }
public class Item
{
public string MyCustomProperty { get; set; }
public string MyAnotherCustomProperty { get; set; }
}
Problem mam tylko z wiązaniem do MyCustomProperty.
Jeśli dziedziczę kontrolkę niestandardową z DataGrid i korzystam z jej kolumn, przepływy danychContext od ItemSource do powiązań w kolumnach po prostu dobrze. Chciałbym zrobić to samo z moją kontrolą niestandardową, która nie dziedziczy po DataGrid. Jaka jest magia kryjąca się za tym, że DataGrid.Columns pobiera kontekst z ItemsSource?
Edit: Zadam inną drogę na ten temat:
Gdybym realizować niestandardowe DataGridColumn
public class MyDataGridColumn : DataGridBoundColumn
{
private Binding _bindingSubText;
public Binding BindingSubText
{
get
{
return _bindingSubText;
}
set
{
if (_bindingSubText == value) return;
var oldBinding = _bindingSubText;
_bindingSubText = value;
OnBindingChanged(oldBinding, _bindingSubText);
}
}
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
var textTextBlock = new TextBlock();
var bindingText = Binding ?? new Binding();
textTextBlock.SetBinding(TextBlock.TextProperty, bindingText);
var textSubTextBlock = new TextBlock();
var bindingSubText = BindingSubText ?? new Binding();
textSubTextBlock.SetBinding(TextBlock.TextProperty, bindingSubText);
var stackPanel = new StackPanel() { Orientation = Orientation.Vertical };
stackPanel.Children.Add(textTextBlock);
stackPanel.Children.Add(textSubTextBlock);
return stackPanel;
}
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
// I don't want to edit elements
return null;
}
}
i spróbuj użyć go w XAML tak:
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<my:MyDataGridColumn Binding="{Binding MyCustomProperty}" BindingSubText="{Binding MyAnotherCustomProperty}" />
</DataGrid.Columns>
</DataGrid>
Powiązanie dla BindingSubText Właściwość nadal będzie pochodzić z DataContext z rodzica DataGrid, oferując mi przedmioty. MyAnotherCustomProperty miałoby skórki w projektancie, ale działałoby to poprawnie w środowisku wykonawczym (ze względu na dynamiczne powiązanie). Mój problem polega na tym, że gdy ktoś inny użyje tej niestandardowej kolumny DataGridCoolumn, będzie musiał to wiedzieć i będzie miał "zły" IntelliSense dla powiązania.
W jaki sposób jest kontekst dla właściwości Binding zestawu DataGridColumn, aby system IntelliSense działał zgodnie z oczekiwaniami?
pochodzi z ItemsControl i zarządza nimi, od czego czerpiecie kontrolę? – ZSH
Mój pochodzi również z ItemsControl. –
jak zdefiniowałeś (tworząc tester)? –
ZSH