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

时间:2012-02-15 17:12:52

标签: wpf xaml

标题为, 我在SO中看到过类似问题thisthis的情侣,但我没有看到它的解决方案。

我知道如果我需要绑定到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>

代码隐藏:

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

    public Window1()
    {
        InitializeComponent();
        MyText = "ABC";
    }
}

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

3 个答案:

答案 0 :(得分:15)

修改

最佳解决方案IMO是@Saad Imran在{SO posted中的question ......

使用此解决方案,您只需命名窗口并绑定到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; }
}

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

MyText = "ABC";
InitializeComponent();

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

答案 1 :(得分:10)

当然

有许多类型的绑定。最基本的绑定到DataContext上的属性,该属性通常从父对象继承

<DataTemplate DataType="{x:Type MyModel}">
    <!-- DataContext is object of type MyModel -->
    <local:MyView />
</DataTemplate>

或者

<Window x:Name="MyWindow">
    <!-- DataContext Inherited from Window -->
    <TextBlock Text="{Binding SomeProperty}" /> 
</Window>

,其中

var SomeObject = new SomeModel();
SomeObject.SomeProperty = "Test";
myWindow.DataContext = SomeObject;

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

<StackPanel>
    <CheckBox x:Name="SomeCheckBox" />
    <TextBlock Text="{Binding ElementName=SomeCheckBox, Path=IsChecked}" />
</StackPanel>

<local:MyUserControl x:Name="SomeUserControl">
    <Button Command="{Binding ElementName=SomeUserControl, Path=DataContext.SaveCommand}" />
</local:MyUserControl >

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

<Window Title="Test">
    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Title}" />
</Window>

<local:MyUserControl>
    <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=DataContext.SaveCommand}" />
</local:MyUserControl >

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

<Button Content="Test">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <TextBlock Text="{TemplateBinding Content}" />
        </ControlTemplate>
    </Button.Template>
</Button>

答案 2 :(得分:5)

当然,您可以使用ElementName

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

    ...

    <TextBox Text="{Binding Path=Foo, ElementName=root}" />

您也可以使用RelativeSource执行此操作,但语法更加丑陋......