【问题标题】:How can I bind a command of a control in template to my ViewModel如何将模板中的控件命令绑定到我的 ViewModel
【发布时间】:2009-11-17 12:29:05
【问题描述】:

对,我有的是:

<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 按钮放在那里。

像这样:

但是,如您所见,我尝试将 X(关闭)按钮的命令绑定到 ViewModel 中的 CloseCommand。假设我的 ViewModel 是正确的,并且我对 WPF 数据绑定的东西缺乏了解是问题所在,那么我做错了什么?不能按照我尝试的方式完成吗?

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

编辑: 由于 Sam 建议未设置我的窗口的 DataContext,我将澄清它已设置,但在创建 MainWindow 时在 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();
    }
}

【问题讨论】:

    标签: c# wpf data-binding command


    【解决方案1】:

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

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

    空的 {Binding} 语句表示“将属性绑定到此控件的 DataContext”。

    或者,您可以在设置 Command 绑定的地方使用 RelativeSource 绑定。比如:

    <Button DockPanel.Dock="Right" 
      Command="{Binding Path=DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType={x:Type HeaderedContentControl}}}">...</Button>
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 其实很抱歉,确实如此。 App.Xaml.cs 通过 OnStartup 函数为我的主窗口设置数据上下文。
      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 2015-10-30
      • 2020-12-21
      • 1970-01-01
      • 2016-10-18
      • 2017-06-15
      相关资源
      最近更新 更多