Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(WPF/C#)绑定到方法内的对象_C#_Wpf_Xaml - Fatal编程技术网

(WPF/C#)绑定到方法内的对象

(WPF/C#)绑定到方法内的对象,c#,wpf,xaml,C#,Wpf,Xaml,为了更好地理解DataContext和绑定,我尝试制作一个示例,其中TextBlock显示对象的属性,属性值由Dispatcher决定。但是,TextBlock不会显示任何值 MainWindow.xaml: <Window x:Class="SfGauge.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microso

为了更好地理解DataContext和绑定,我尝试制作一个示例,其中TextBlock显示对象的属性,属性值由Dispatcher决定。但是,TextBlock不会显示任何值

MainWindow.xaml:

<Window x:Class="SfGauge.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid DataContext="{Binding myObj, Mode=TwoWay}">
    <TextBlock Text="{Binding RandomVal}">
    </TextBlock>
</Grid>
ObservieObject.cs

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
 
    protected void OnPropertyChanged([CallerMemberName] string propName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
 
    protected bool SetProperty<T>(ref T storage, T value,
        [CallerMemberName] String propertyName = null)
    {
        if (Equals(storage, value)) return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}
公共类ObserveObject:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
 
受保护的void OnPropertyChanged([CallerMemberName]string propName=null)
    {
var handler=PropertyChanged;
if(处理程序!=null)
        {
处理程序(此,新PropertyChangedEventArgs(propName));
        }
    }
 
受保护的布尔集合属性(参考T存储,T值,
[CallerMemberName]字符串propertyName=null)
    {
if(等于(存储,值))返回false;
储存=价值;
OnPropertyChanged(propertyName);
返回true;
    }
}

以编程方式将
DataContext
设置为
myObj

public MainWindow()
{
    InitializeComponent();

    DataContext = myObj; //<--

    DispatcherTimer aTimer;
    aTimer = new DispatcherTimer();
    aTimer.Interval += TimeSpan.FromSeconds(1);
    aTimer.Tick += Timer_Tick;
    aTimer.Start();
}
您只能绑定到公共属性。如果将
myObj
定义为窗口类的公共属性,也可以在XAML标记中这样绑定到它:

<Grid DataContext="{Binding myObj, RelativeSource={RelativeSource AncestorType=Window}}">

元素的
DataContext
基本上只是一个对象。
DataContext
的默认值是元素父元素的
DataContext
,例如:

myTextBlock.DataContext = myTextBloc.Parent.DataContext
这是不“正确的”,但它说明了
DataContext
是如何向下渗透的。这一直到顶部元素(在本例中为
Window
)。
窗口的
DataContext
默认为
null

当您试图绑定
Grid
DataContext
时,
Binding
使用
Grid
DataContext
查找属性
myObj
Grid
DataContext
窗口。DataContext
null
,这将使
绑定无法工作

为了能够绑定到
窗口
本身的属性,您必须将
窗口
设置为自身的
数据上下文

public MainWindow()
{
    this.DataContext = this;

    ...
}
另外:您只能绑定到属性,因此必须将
myObj
设置为属性:

public randomValue myObj { get; set; } = new randomValue()
这样做会使绑定按预期工作


或者,您也可以按照@mm8的建议直接设置
文本块的
数据上下文。

谢谢您直观的回答!如果可以的话,我会+1:)顺便说一句,我可以看到只有当属性randomValue为public时,这才有效。但是计时器方法仍然可以访问它,所以它影响的似乎只有绑定。绑定只能访问公共属性吗?通常是。然而,这是一个特例:因为XAML和代码隐藏在技术上是同一个类,
绑定
可以访问私有属性。“绑定可以访问私有属性”是错误的。WPF数据绑定仅适用于公共属性,无论它们在何处声明。
public MainWindow()
{
    this.DataContext = this;

    ...
}
public randomValue myObj { get; set; } = new randomValue()