Моя проблема аналогична описанной в этом вопросе:
WPF MVVM Управление привязкой кнопок в DataTemplate
Вот мой XAML:
<Window x:Class="MissileSharp.Launcher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MissileSharp Launcher" Height="350" Width="525">
<Grid>
<!-- when I put the button here (outside the list), the binding works -->
<!--<Button Content="test" Command="{Binding Path=FireCommand}" />-->
<ListBox ItemsSource="{Binding CommandSets}">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- I need the button here (inside the list), and here the binding does NOT work -->
<Button Content="{Binding}" Command="{Binding Path=FireCommand}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Это просто a ListBox
, связанный с ObservableCollection<string>
с именем CommandSets
(который находится в ViewModel).
Эта привязка работает (она отображает кнопку для каждого элемента в коллекции).
Теперь я хочу привязать кнопку к команде (FireCommand
), которая также находится в ViewModel.
Здесь соответствующая часть ViewModel:
public class MainWindowViewModel : INotifyPropertyChanged
{
public ICommand FireCommand { get; set; }
public ObservableCollection<string> CommandSets { get; set; }
public MainWindowViewModel()
{
this.FireCommand = new RelayCommand(new Action<object>(this.FireMissile));
}
private void FireMissile(Object obj)
{
System.Windows.MessageBox.Show("fire");
}
}
Связывание этой кнопки НЕ работает.
Из того, что я понял из question, связанного выше, привязка не работает, потому что:
(исправьте меня, если я ошибаюсь)
- Кнопка находится внутри
ListBox
, поэтому она "знает" привязкуListBox
(в этом случаеObservableCollection
), но не привязка главного окна - Я пытаюсь связать команду в главной ViewModel главного окна (которое кнопка не знает)
Сама команда определенно правильна, потому что, когда я нажимаю кнопку вне ListBox
(см. выше приведенный выше пример XAML), выполняется работа по связыванию и команда.
По-видимому, мне просто нужно указать кнопке привязку к основной ViewModel формы.
Но я не могу понять правильный синтаксис XAML.
Я попробовал несколько подходов, которые я нашел после некоторых поисковых запросов, но никто из них не работал у меня:
<Button Content="{Binding}" Command="{Binding RelativeSource={RelativeSource Window}, Path=DataContext.FireCommand}" />
<Button Content="{Binding}" Command="{Binding Path=FireCommand, Source={StaticResource MainWindow}}" />
<Button Content="{Binding}" Command="{Binding Path=FireCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
Может кто-то угодить:
- дайте мне правильный XAML, чтобы связать кнопку внутри
ListBox
с командой в формеMainViewModel
? - укажите мне ссылку, где этот расширенный материал привязки объясняется так, как может понять начинающий WPF/MVVM?
Мне кажется, что я просто копирую и вставляю тайные заклинания XAML, и до сих пор у меня нет никакой подсказки (и я не могу найти хорошую документацию), как бы я сам разобрался, в каких случаях мне понадобитсяRelativeSource
илиStaticResource
или что-то другое вместо "нормального" связывания.