代码之家  ›  专栏  ›  技术社区  ›  Sekhat

如何将模板中控件的命令绑定到ViewModel

  •  0
  • Sekhat  · 技术社区  · 16 年前

    <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(close)按钮的命令绑定到ViewModel中的close命令。假设我的ViewModel是正确的,并且我对WPF数据绑定的理解不足是问题所在,那么我做错了什么?不能用我现在的方式来做吗?

    (注意:出于这个问题的目的,我将窗口使用的所有资源合并到windows资源字典中。)

    因为Sam建议我的窗口的DataContext没有设置,所以我将澄清它是设置的,但是在App.Xaml创建主窗口时在代码隐藏中完成。

    /// <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 回复  |  直到 11 年前
        1
  •  2
  •   Samuel Jack    16 年前

    这是另一个尝试。您的按钮位于HeaderedContentControl标题的数据模板中。此数据模板与父控件具有不同的数据上下文。它的数据上下文隐式地是Header属性的值。因此,要解决您的问题,您需要

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

    <Button DockPanel.Dock="Right" 
      Command="{Binding Path=DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType={x:Type HeaderedContentControl}}}">...</Button>
    
        2
  •  0
  •   Samuel Jack    16 年前

    在按钮中指定绑定的路径,但不指定数据源。我认为您缺少的是将窗口的DataContext设置为ViewModel。你需要像这样的东西

    <Window ... DataContext="{StaticResource myViewModel}">
    ...
    
    推荐文章