Почему бы просто не использовать QuestionsListBox.DataContext
внутри ChoiceAddButton_Click
напрямую?У вас есть прямой способ ссылаться на внешний ListBox
из вашего кода, поскольку вы дали ему имя, а DataContext
является доступным свойством.
private void ChoiceAddButton_Click(object sender, RoutedEventArgs e)
{
...
var outerLBDataContext= QuestionsListBox.DataContext;
...
}
Это прекрасно работает для меня вдемонстрационное решение с использованием предоставленного вами XAML.
Редактировать 2:
Извините, не думал.Button
DataContext
будет Choice
, а не Choices
коллекцией.
Ваш внутренний ListBox
DataContext
равен , а не a Question
, это Choices
.Ваш внешний TextBox
имеет Question.Question
в качестве DataContext
.Привязка Text
или ItemsSource
указывает DataContext
на цель привязки.Вот немного хитрого XAML, чтобы проникнуть в DataContext
ссылку.
Добавьте ElementName
к своему внешнему TextBox
:
<TextBox Text="{Binding Question, Mode=TwoWay}" Grid.Row="0" HorizontalAlignment="Stretch" TextWrapping="Wrap" ElementName="questionTextBox"/>
Теперь добавьте скрытый TextBlock внутриваш внутренний ListBox
:
<ListBox Name="ChoicesListBox" ItemsSource="{Binding Choices}" Grid.Row="1" HorizontalAlignment="Stretch" ItemContainerStyle="{StaticResource ListItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Click="ChoiceAddButton_Click" Height="72" Width="72" HorizontalAlignment="Left" BorderBrush="Transparent">
<Button.Background>
<ImageBrush ImageSource="/Images/choices.add.png" Stretch="Fill" />
</Button.Background>
</Button>
<TextBox Text="{Binding Value, Mode=TwoWay}" HorizontalAlignment="Stretch" Grid.Column="1" Margin="-20,0" />
<TextBlock Name="hiddenTextBlock" Visibility="Collapsed" DataContext="{Binding ElementName=questionTextBox, Path=DataContext}"
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Наконец, внутри вашего обработчика событий вы можете перемещаться по дереву, чтобы получить эту ссылку:
private void ChoiceAddButton_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
if(btn == null) return; //won't happen when this method handles the event
Grid g = btn.Parent as Grid;
if(g!=null) // also unlikely to fail
{
TextBlock tb = g.FindName("hiddenTextBlock") as TextBlock;
if(tb!=null) // also unlikely to fail, but never hurts to be cautious
{
var currentQuestion = tb.DataContext;
// now you've got the DC you want
}
}
}
Я хотел бы отметить, что этоне совсем элегантное решение.Однако это решение для всего пользовательского интерфейса, которое может оказаться полезным.Но лучше было бы включить Parent
ссылки в классы Choice
и ChoiceList
(или как они там называются) и использовать их.Тогда это будет так же просто, как вызов btn.DataContext.Parent.Parent
с соответствующими преобразованиями типов.Таким образом, ваш код станет проще для чтения и обслуживания.