如何使用StaticResource在XAML中定义DataContext

7
我希望能够通过XAML中的静态资源声明DataContext,将其作为Northwind数据库中客户的绑定。我可以在代码(C#)中轻松实现此操作,但想学习如何在XAML中实现。我已经尝试了所有我能找到的例子,但都无法正常工作。我相信问题出在我标记为[Option1]和[Option2]的两行XAML代码中。您能否澄清这个语法应该是什么样子的?
namespace DataGridEF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            bModel1 bNorthWind = new bModel1();
            //this.DataContext = bNorthWind;
            bNorthWind.GetCustomers();
        }
    }
}

namespace DataGridEF
{
    public class bModel1
    {
        List<Customer> _Customers;
        public List<Customer> Customers
        {
            get { return _Customers; }
            set { _Customers = value; }
        }

        public void GetCustomers()
        {
            NorthwindEntities NorthWind = new NorthwindEntities();
            var CustomerQ = from cust in NorthWind.Customers select cust;
            _Customers = CustomerQ.ToList();
        }

    }
}

XAML

 <Window x:Class="DataGridEF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:vm="clr-namespace:DataGridEF">

<Window.Resources>
    <vm:bModel1 x:Key="TheViewModel" />
</Window.Resources>

<Grid>
    <DataGrid AutoGenerateColumns="False" Height="195" 
              HorizontalAlignment="Left" Margin="20,89,0,0" 
              Name="dataGrid1" ItemsSource="{Binding Path=Customers}" 
              [option1]DataContext="{StaticResource TheViewModel}"
              [option2]DataContext=
                  "{Binding Path=., Source={StaticResource TheViewModel}}"
              VerticalAlignment="Top" Width="471" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=ContactName}" />
            <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}" />
            <DataGridTextColumn Header="City" Binding="{Binding Path=City}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>
</Window>

一旦您在XAML中设置了Window.DataContext( <Window.DataContext><vm:bModel1 /></Window.DataContext>),您就不需要在数据网格上设置DataContext - Zev Spitz
3个回答

9
如果不考虑实体框架和MSSQL NorthWind数据库,那么codeproject的Example2示例代码提供了很好的说明。 " WPF/MVVM快速入门教程"
对于您的XAML,您应该将其开头更改为:
<Window x:Class="DataGridEF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:vm="clr-namespace:DataGridEF">

<Window.DataContext>
        <vm:bNorthWind />
    </Window.DataContext>
<Grid>
<!---Couldnt check your code due to dependencies on 
     EF and MSSQL NorthWind database

     See the reference for working illustration sample:
 http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial

-->
</Grid>
</Window>

另一种类似的方法在"在编码中设置DataContext与在XAML中设置有什么优势?"中可以看到,这部分内容如下:
    <StackPanel.DataContext>
        <local:CustomerViewModel />
    </StackPanel.DataContext>   

DataContext定义从代码后台迁移到XAML与使用StaticResourceDynamicResource无关。请参见:WPF中StaticResource和DynamicResource的区别是什么? 可能在codeproject中更好地解决 WPF:StaticResource vs. DynamicResource 相关、有用和进一步阅读:

1
我更喜欢将键设置为静态字符串 - WPF已经有足够多的神奇字符串了,如果不必要就不要让自己陷入重构的困境。
App.xaml 中。
xmlns:viewModels="clr-namespace:MyAppNamespace.ViewModels"
xmlns:local="clr-namespace:tvCADdesktop"
x:Name="App"
...
<viewModels:ApplicationViewModel x:Key= "{x:Static local:App.MainVmResourceKey}"/>

App.xaml.cs

public static readonly string MainVmResourceKey = "MainVm";

在我的各种 Control.xaml 中。
<UserControl.DataContext>
    <Binding>
        <Binding.Source>
            <StaticResource ResourceKey="{x:Static app:App.MainVmResourceKey}" />
        </Binding.Source>
    </Binding>
</UserControl.DataContext>

请注意,UserControl 部分是您想要将 ViewModel 应用于的任何类型。

0
<Window xmlns:vm="clr-namespace:YourApplication.ViewModels">

    <Window.Resources>
        <vm:MainWindowViewModel x:Key="MWVM" />
    </Window.Resources>

    <Window.DataContext>
        <StaticResource ResourceKey="MWVM" />
    </Window.DataContext>

</Window>

编辑:

与其他答案不同,这个答案试图简单地向您展示如何在XAML中将ViewModel定义为StaticResource,并使用该资源作为DataContext。


2
使用静态资源与直接设置Window.DataContext有什么好处吗?如果没有,那么这个答案建议直接设置它。 - Zev Spitz
@ZevSpitz - 是的,当您将属性从主ViewModel(Window的DataContext)绑定到具有自己的ViewModel的UserControl时,确实会有好处。如果您尝试在XAML中将主ViewModel的属性绑定到UserControl,则不起作用,甚至会收到警告。因此,您必须引用主ViewModel。像这样:<controls:MyUserControl Title="{Binding Path=Title, Source={StaticResource ResourceKey=MWVM}}" /> - n0kx
我认为这还不足以成为一个充分的理由。如果你需要担心这种情况,你可以使用{Binding Path=DataContext.Title, RelativeSource={RelativeSource AncestorType=Window}} - Zev Spitz
@ZevSpitz 那当然也可以。但它需要更长的绑定并且提供较少的灵活性,如果你需要那种东西的话。 - n0kx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接