Как я могу привязать команду элемента управления в шаблоне к моей модели представления - PullRequest
0 голосов
/ 17 ноября 2009

Да, у меня есть:

<Window x:Class="WpfGettingThingsDone.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    AllowsTransparency="True"
    Background="Transparent"
    WindowStyle="None"    
    Title="{Binding Title}" Height="300" Width="300">
    <Window.Resources>
        <ResourceDictionary>
            <Style x:Key="WindowBorderBackground" TargetType="{x:Type Border}">
                <Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush StartPoint="0,1" EndPoint="1,0">
                            <GradientStop Color="#FF222222" Offset="0" />
                            <GradientStop Color="#FF222222" Offset="0.2" />
                            <GradientStop Color="#FFAAAAAA" Offset="0.6" />
                            <GradientStop Color="#FF222222" Offset="0.7" />
                            <GradientStop Color="#FFAAAAAA" Offset="0.9" />
                            <GradientStop Color="#FF222222" Offset="1" />
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style x:Key="WindowHeaderedContent" TargetType="{x:Type HeaderedContentControl}">
                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Border 
                                Background="Black"
                                BorderBrush="Black" 
                                BorderThickness="1"
                                CornerRadius="5,5,0,0"
                                Padding="4"
                                SnapsToDevicePixels="True"
                                >
                                <DockPanel>
                                    <Button DockPanel.Dock="Right" Command="{Binding Path=CloseCommand}">X</Button>
                                    <TextBlock
                                        FontSize="14"
                                        FontWeight="Bold"
                                        Foreground="White"
                                        HorizontalAlignment="Center"
                                        Text="{TemplateBinding Content}" />
                                </DockPanel>
                            </Border>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>

    <Border CornerRadius="5" Style="{StaticResource WindowBorderBackground}">
        <HeaderedContentControl Header="Current Contexts" 
                                Style="{StaticResource WindowHeaderedContent}" 
                                >
        </HeaderedContentControl>
    </Border>
</Window>

В основном рисует окно с красивым градиентным фоном, используя HeaderedContentControl для создания строки заголовка, который использует HeaderTemplate, чтобы поместить туда кнопку x.

Вот так:

alt text

Однако, как вы можете видеть, я пытался связать команду кнопки X (закрыть) с командой CloseCommand в моей ViewModel. Если предположить, что моя ViewModel верна и что мое понимание проблем с привязкой данных WPF является проблемой, что я делаю неправильно? Разве это не может быть сделано так, как я пытаюсь?

(Примечание: для целей этого вопроса я объединил все ресурсы, используемые окном, в словарь ресурсов Windows.)

Редактировать: Так как Сэм предположил, что мой DataContext для моего окна не установлен, я поясню, что он установлен, но выполняется в коде для App.Xaml при создании MainWindow.

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        MainWindow mainWindow = new MainWindow();            
        var viewModel = new MainWindowViewModel();

        viewModel.RequestClose += (s, ev) => mainWindow.Close();

        mainWindow.DataContext = viewModel;

        mainWindow.Show();
    }
}

Ответы [ 2 ]

2 голосов
/ 17 ноября 2009

Вот еще одна попытка. Ваша кнопка находится в шаблоне данных для заголовка HeaderedContentControl. Этот шаблон данных имеет контекст данных, отличный от родительского элемента управления. Это контекст данных неявно значение свойства Header. Таким образом, чтобы решить вашу проблему, вам нужно сделать

<HeaderedContentControl Header="{Binding}" .../>

Пустой оператор {Binding} означает «привязать свойство к DataContext этого элемента управления».

В качестве альтернативы, вы можете использовать привязку RelativeSource, где вы устанавливаете привязку Command. Что-то вроде:

<Button DockPanel.Dock="Right" 
  Command="{Binding Path=DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType={x:Type HeaderedContentControl}}}">...</Button>
0 голосов
/ 17 ноября 2009

В вашей кнопке вы указываете путь привязки, но не источник данных. Я думаю, что вам не хватает, чтобы установить DataContext вашего окна быть ViewModel. Вам нужно что-то вроде

<Window ... DataContext="{StaticResource myViewModel}">
...
...