wpf 是否可以在不设置 DataContext 的情况下绑定代码隐藏属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9297939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to bind code-behind property without setting DataContext?
提问by King Chan
As titled, I seen couples of similiar question thisor thisin SO, but I don't see a solution for it.
正如标题,我看到similiar问题的夫妇本或本在左右,但我没有看到它的解决方案。
I know if I need to bind to the code-beind, I need to set Datacontext = this
我知道如果我需要绑定到代码隐藏,我需要设置 Datacontext = this
But my problem is that my datacontext already binding to my ViewModel, but I want to do some UI manipulation with using Command which is defined in the code-beind.
但是我的问题是我的数据上下文已经绑定到我的 ViewModel,但是我想使用在代码隐藏中定义的 Command 来进行一些 UI 操作。
Is it possbile to bind it in xaml? If so, how?
是否可以在 xaml 中绑定它?如果是这样,如何?
EDIT: I did tried the follows:
编辑:我确实尝试了以下方法:
<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>
And code-behind:
和代码隐藏:
public partial class Window1 : Window
{
public string MyText { get; set; }
public Window1()
{
InitializeComponent();
MyText = "ABC";
}
}
I could see the Button2 shows AAAA
, but Button3 shows nothing....
我可以看到 Button2 显示AAAA
,但 Button3 什么也没显示....
回答by Dean Kuga
EDIT
编辑
The best solution IMO is the one postedby @Saad Imran in this SO question...
IMO 的最佳解决方案是@Saad Imran 在这个 SO问题中发布的解决方案......
With this solution all you have to do is name your window and binding to a property in your XAML will be as easy as this {Binding ElementName=MyWindowName, Path=MyText}
使用此解决方案,您只需为您的窗口命名,然后绑定到您的 XAML 中的一个属性就变得如此简单 {Binding ElementName=MyWindowName, Path=MyText}
So, what you are doing with Content="{Binding Path=MyText, ElementName=_Root}"
is exactly right and your Button Content property IS bound to MyText property but the only thing you are missing is change notification (need to implement INotifyPropertyChanged
interface for that) so when you set your MyText property to ABC MyText = "ABC";
no change notification is sent...
因此,您所做Content="{Binding Path=MyText, ElementName=_Root}"
的完全正确,您的 Button Content 属性绑定到 MyText 属性,但您唯一缺少的是更改通知(需要为此实现INotifyPropertyChanged
接口),因此当您将 MyText 属性设置为 ABC 时,MyText = "ABC";
没有更改通知已发送...
Easy way to test this is by setting the MyText property explicitly as such:
测试这一点的简单方法是显式设置 MyText 属性,如下所示:
private string myText = "ABC";
public string MyText
{
get { return myText; }
set { myText = value; }
}
or setting it in the constructor before InitializeComponent()
is called:
或者在InitializeComponent()
调用之前在构造函数中设置它:
MyText = "ABC";
InitializeComponent();
If you do that you'll notice that your button will have ABC as its content but changes to MyText property will not affect the button content because there is no change notification...
如果您这样做,您会注意到您的按钮将 ABC 作为其内容,但对 MyText 属性的更改不会影响按钮内容,因为没有更改通知...
回答by Rachel
Of course
当然
There are many types of bindings. The most basic one binds to a property on the DataContext
, which is usually inherited from a Parent object
有许多类型的绑定。最基本的一个绑定到 上的一个属性,该属性DataContext
通常继承自 Parent 对象
<DataTemplate DataType="{x:Type MyModel}">
<!-- DataContext is object of type MyModel -->
<local:MyView />
</DataTemplate>
Or
或者
<Window x:Name="MyWindow">
<!-- DataContext Inherited from Window -->
<TextBlock Text="{Binding SomeProperty}" />
</Window>
where
在哪里
var SomeObject = new SomeModel();
SomeObject.SomeProperty = "Test";
myWindow.DataContext = SomeObject;
Other binding types include ElementName
, where you can specify the target UI element to use as the data source for the binding
其他绑定类型包括ElementName
,您可以在其中指定目标 UI 元素以用作绑定的数据源
<StackPanel>
<CheckBox x:Name="SomeCheckBox" />
<TextBlock Text="{Binding ElementName=SomeCheckBox, Path=IsChecked}" />
</StackPanel>
or
或者
<local:MyUserControl x:Name="SomeUserControl">
<Button Command="{Binding ElementName=SomeUserControl, Path=DataContext.SaveCommand}" />
</local:MyUserControl >
Or RelativeSource
, which allows you to find an object relative to the current object to use as a DataSource
或者RelativeSource
,它允许您查找与当前对象相关的对象以用作数据源
<Window Title="Test">
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Title}" />
</Window>
or
或者
<local:MyUserControl>
<Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=DataContext.SaveCommand}" />
</local:MyUserControl >
And TemplateBinding
, which binds is a shortcut to a RelativeSource
binding that binds to a templated object
和TemplateBinding
, 其中 binds 是RelativeSource
绑定到模板化对象的绑定的快捷方式
<Button Content="Test">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock Text="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
</Button>
回答by Thomas Levesque
Sure, you can use ElementName
:
当然,您可以使用ElementName
:
<Window Name="root"
Class="..."
...>
...
<TextBox Text="{Binding Path=Foo, ElementName=root}" />
You could also do it with RelativeSource
, but the syntax is uglier...
你也可以用 来做RelativeSource
,但语法更丑......