Я знаю, что на этот вопрос ответили, но ни одно из объяснений не дает понимания DataContext и того, как он работает.Эта ссылка делает большую работу для этого.
ВСЕ, ЧТО ВЫ ХОТИТЕ ЗНАТЬ О БАЗЕ ДАННЫХ В WPF, SILVERLIGHT И WP7 (ЧАСТЬ ВТОРАЯ)
В ответ на ваш вопрос # 1
Почему <UserControl DataContext="{RelativeSource Self}">
не работает?
Это краткое изложение вышеуказанной ссылки.DataContext не должен быть установлен в Self на уровне элемента UserControl.Это потому, что он нарушает наследование DataContext.Если вы установите для него значение self и поместите этот элемент управления в Window или другой элемент управления, он не будет наследовать Windows DataContext.
DataContext наследуется всем нижним элементам XAML и всем XAML UserControls, если он не перезаписан где-либо.При установке UserControl DataContext на себя, это перезаписывает DataContext и нарушает Наследование.Вместо этого вложите один элемент в XAML, в вашем случае, в StackPanel.Поместите здесь привязку DataContext и привяжите ее к UserControl.Это сохраняет наследство.
См. Также приведенную ниже ссылку для подробного объяснения этого.
ПРОСТОЙ РИСУНОК ДЛЯ СОЗДАНИЯ ПОВТОРНЫХ ИСПОЛЬЗОВАННЫХ УПРАВЛЕНИЙ В WPF / SILVERLIGHT
Inответ на ваш вопрос # 2
Каков наилучший способ сделать что-то подобное?
См. пример кода ниже.
<UserControl x:Class="Namespace.ColorWithText" Name="ThisControl">
<StackPanel Orientation="Horizontal" DataContext={Binding ElementName=ThisControl}>
<Border Width="15" Height="15" Background="{Binding Color" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
Обратите внимание, что как только выДля этого вам не понадобится ElementName для каждой привязки.