是否可以在不设置DataContext的情况下绑定代码隐藏属性?

Kin*_*han 14 wpf xaml

正如标题,我看到similiar问题的夫妇在左右,但我没有看到它的解决方案.

我知道如果我需要绑定到code-beind,我需要设置 Datacontext = this

但我的问题是我的datacontext已经绑定到我的ViewModel,但我想使用在code-beind中定义的Command进行一些UI操作.

是否可以在xaml中绑定它?如果是这样,怎么样?

编辑:我确实尝试了以下内容:

<Window x:Class="WpfApplication3.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" x:Name="_Root">
<Grid x:Name="hellogrid">
    <TextBlock x:Name="myTextBlock" Text="AAAA"/>
    <Button Margin="82,119,121,120" Name="button2" Content="{Binding Path=Text, ElementName=myTextBlock}"/>
    <Button Margin="82,72,121,0" Name="button3" Content="{Binding Path=MyText, ElementName=_Root}" Height="23" VerticalAlignment="Top" />
</Grid>
Run Code Online (Sandbox Code Playgroud)

代码隐藏:

public partial class Window1 : Window
{
    public string MyText { get; set; }

    public Window1()
    {
        InitializeComponent();
        MyText = "ABC";
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以看到Button2显示AAAA,但Button3没有显示任何内容....

Dea*_*uga 15

编辑

最好的解决方案IMO是@Saad Imran在这个SO 问题中发布的解决方案......

使用此解决方案,您只需命名窗口并绑定到XAML中的属性就像这样简单 {Binding ElementName=MyWindowName, Path=MyText}

所以,你正在做的Content="{Binding Path=MyText, ElementName=_Root}"是完全正确的,你的Button Content属性绑定到MyText属性,但你唯一缺少的是更改通知(需要实现INotifyPropertyChanged接口),所以当你将MyText属性设置为ABC时MyText = "ABC";没有更改通知已发送...

测试这个的简单方法是通过显式设置MyText属性:

private string myText = "ABC";
public string MyText
{
   get { return myText; }
   set { myText = value; }
}
Run Code Online (Sandbox Code Playgroud)

或者在InitializeComponent()调用之前在构造函数中设置它:

MyText = "ABC";
InitializeComponent();
Run Code Online (Sandbox Code Playgroud)

如果您这样做,您会注意到您的按钮将ABC作为其内容,但更改为MyText属性不会影响按钮内容,因为没有更改通知...


Rac*_*hel 10

当然

有许多类型的绑定.最基本的一个绑定到一个属性DataContext,它通常从一个Parent对象继承

<DataTemplate DataType="{x:Type MyModel}">
    <!-- DataContext is object of type MyModel -->
    <local:MyView />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

要么

<Window x:Name="MyWindow">
    <!-- DataContext Inherited from Window -->
    <TextBlock Text="{Binding SomeProperty}" /> 
</Window>
Run Code Online (Sandbox Code Playgroud)

哪里

var SomeObject = new SomeModel();
SomeObject.SomeProperty = "Test";
myWindow.DataContext = SomeObject;
Run Code Online (Sandbox Code Playgroud)

其他绑定类型包括ElementName,您可以在其中指定要用作绑定的数据源的目标UI元素

<StackPanel>
    <CheckBox x:Name="SomeCheckBox" />
    <TextBlock Text="{Binding ElementName=SomeCheckBox, Path=IsChecked}" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

要么

<local:MyUserControl x:Name="SomeUserControl">
    <Button Command="{Binding ElementName=SomeUserControl, Path=DataContext.SaveCommand}" />
</local:MyUserControl >
Run Code Online (Sandbox Code Playgroud)

或者RelativeSource,它允许您查找相对于当前对象的对象以用作DataSource

<Window Title="Test">
    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Title}" />
</Window>
Run Code Online (Sandbox Code Playgroud)

要么

<local:MyUserControl>
    <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=DataContext.SaveCommand}" />
</local:MyUserControl >
Run Code Online (Sandbox Code Playgroud)

并且TemplateBinding,绑定是RelativeSource绑定到模板化对象的绑定的快捷方式

<Button Content="Test">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <TextBlock Text="{TemplateBinding Content}" />
        </ControlTemplate>
    </Button.Template>
</Button>
Run Code Online (Sandbox Code Playgroud)

  • 这是WPF中绑定的一般概述,而不是他的问题的答案...... (2认同)

Tho*_*que 5

当然,你可以使用ElementName:

<Window Name="root"
        Class="..."
        ...>

    ...

    <TextBox Text="{Binding Path=Foo, ElementName=root}" />
Run Code Online (Sandbox Code Playgroud)

你也可以这样做RelativeSource,但语法更加丑陋......

  • @KingChan,这是因为你在调用`InitializeComponent`之后设置了MyText属性*,因此在更改之前已经检索了该值.由于您的类没有实现`INotifyPropertyChanged`,并且您的属性不是依赖属性,绑定引擎无法知道值已更改,因此它不会刷新按钮的内容. (2认同)