C# WPF XAML绑定不更新
我有一个WPF项目,其中有4个C# WPF XAML绑定不更新,c#,wpf,binding,C#,Wpf,Binding,我有一个WPF项目,其中有4个TextBlock。我想要的是通过Binding更改每个TextBlock的文本 到目前为止,我有我的XAML: 在我的代码中,我有: 公共部分类主窗口:窗口 { 公共字符串FirstString{get;set;} 公共字符串SecondString{get;set;} 公共字符串第三个字符串{get;set;} 公共字符串第四个字符串{get;set;} 公共主窗口() { 初始化组件(); FirstString=“First”; SecondString
TextBlock
。我想要的是通过Binding
更改每个TextBlock
的文本
到目前为止,我有我的XAML:
在我的代码中,我有:
公共部分类主窗口:窗口
{
公共字符串FirstString{get;set;}
公共字符串SecondString{get;set;}
公共字符串第三个字符串{get;set;}
公共字符串第四个字符串{get;set;}
公共主窗口()
{
初始化组件();
FirstString=“First”;
SecondString=“Second”;
ThirdString=“第三”;
第四字符串=“第四”;
}
}
但是绑定根本不起作用。我做错什么了吗
编辑:
按照Chris Mantle在评论中的建议查看调试输出(我必须为绑定启用警告),我得到以下错误:
System.Windows.Data信息:10:无法使用绑定检索值,且不存在有效的回退值;改为使用默认值。BindingExpression:Path=FirstString;DataItem=null;目标元素是“TextBlock”(Name='First');目标属性为“Text”(类型为“String”)
除非另有规定,否则绑定的路径是相对于元素的DataContext
。在您的情况下,我怀疑您根本没有指定DataContext
由于属性是在main窗口
类本身中声明的,因此最简单的修复方法是添加:
DataContext = this;
在构造函数的末尾。由于您没有通知第一个字符串
、第二个字符串
、第三个字符串
和第四个字符串
已更改,因此更改不会反映在UI中。您可以实现INotifyPropertyChanged
,也可以处理dependencProperty
也设置您的Datacontext
IMHOdependencProperty
更适合此用途。以下是一个例子:
public partial class MainWindow : Window
{
#region Public
public string FirstString
{
get { return (string)GetValue(FirstStringProperty); }
set { SetValue(FirstStringProperty, value); }
}
public string SecondString
{
get { return (string)GetValue(SecondStringProperty); }
set { SetValue(SecondStringProperty, value); }
}
public string ThirdString
{
get { return (string)GetValue(ThirdStringProperty); }
set { SetValue(ThirdStringProperty, value); }
}
public string FourthString
{
get { return (string)GetValue(FourthStringProperty); }
set { SetValue(FourthStringProperty, value); }
}
#region Dependency Properties
public static readonly DependencyProperty FirstStringProperty = DependencyProperty.Register("FirstString", typeof(string), typeof(MainWindow), new PropertyMetadata("default value"));
public static readonly DependencyProperty SecondStringProperty = DependencyProperty.Register("SecondString", typeof(string), typeof(MainWindow), new PropertyMetadata("default value"));
public static readonly DependencyProperty ThirdStringProperty = DependencyProperty.Register("ThirdString", typeof(string), typeof(MainWindow), new PropertyMetadata("default value"));
public static readonly DependencyProperty FourthStringProperty = DependencyProperty.Register("FourthString", typeof(string), typeof(MainWindow), new PropertyMetadata("default value"));
#endregion
#endregion
public MainWindow()
{
InitializeComponent();
FirstString = "First";
SecondString = "Second";
ThirdString= "Third";
FourthString= "Fourth";
this.DataContext = this;
}
}
有几件事是不正确的。Binding
标记将查看控件的DataContext
属性中的对象。除非另有指定,否则此属性从声明的父级继承DataContext
。对于窗口
控件,这是开箱即用的null
这个问题有两种选择。您可以在代码隐藏或XAML中明确设置DataContext
// In XAML
<Window DataContext={Binding RelativeSource={RelativeSource Self}}>
or
// In the code-behind
DataContext = this;
我建议您创建另一个类MainWindowViewModel
public class MainWindowViewModel
{
public string FirstString { get; set; }
public string SecondString { get; set; }
public string ThirdString { get; set; }
public string FourthString { get; set; }
public MainWindowViewModel()
{
FirstString = "First";
SecondString = "Second";
ThirdString= "Third";
FourthString= "Fourth";
}
}
然后在调用window类上的show之前设置MainWindow对象的DataContext
MainWindow wnd = new MainWindow();
wnd.DataContext = new MainWindowViewModel();
wnd.Show();
您可以通过从App.xaml中删除StartupUri=“MainWindow.xaml”来完成最后一点,并通过覆盖App.xaml.cs中的OnStartup来手动创建和显示主窗口。应该是这样工作的
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="First" Text="{Binding FirstString}" Grid.Row="0"/>
<TextBlock x:Name="Second" Text="{Binding SecondString}" Grid.Row="1"/>
<TextBlock x:Name="Third" Text="{Binding ThirdString}" Grid.Row="2"/>
<TextBlock x:Name="Fourth" Text="{Binding FourthString}" Grid.Row="3"/>
</Grid>
输出窗口中有什么东西吗?什么都没有。我找不到原因。你能在输出窗口中打开数据绑定信息,看看是否还有更多细节吗?(工具菜单–>选项–>调试–>输出窗口–>WPF跟踪设置–>数据绑定,设置为Verbose或All)谁是窗口的数据上下文。应该是这样,我使用了DataContext=this;但仍然没有。移动InitializeComponent();在构造器的底部,您至少应该看到一些东西。不过尼古拉斯是对的,你写的DataContext=this;将其移至底部无需执行此操作,因为代码位于xaml后面,当上下文发生更改时,它将自动通知…@Arun我没有遵循您的逻辑。如果属性不是INPC属性,也不是依赖属性,则对属性的更改不会反映到UI中。在这种简单的情况下,在设置属性后设置DataContext=this
将起作用,因为DataContext
是一个依赖属性。但代码中的任何进一步更改都不会反映出来。@oimitro这是一个非常做作的示例,可以工作。但要注意,这远远不是最佳实践。您通常会有另一个对象(我们称之为视图模型)来实现该接口,该对象将被分配到视图的(本例中为窗口)DataContext
。如果您想在WPF的上下文中阅读有关MVVM模式的更多信息,可以查看。@Sinon Belanger MainWindowViewModel.Oh类上没有InitializeComponent()方法。很抱歉没有意识到这是一个视图模型。删除我的评论。您的示例中缺少第二个引号,位于ThirdString=“Third
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="First" Text="{Binding FirstString}" Grid.Row="0"/>
<TextBlock x:Name="Second" Text="{Binding SecondString}" Grid.Row="1"/>
<TextBlock x:Name="Third" Text="{Binding ThirdString}" Grid.Row="2"/>
<TextBlock x:Name="Fourth" Text="{Binding FourthString}" Grid.Row="3"/>
</Grid>
public string FirstString { get; set; }
public string SecondString { get; set; }
public string ThirdString { get; set; }
public string FourthString { get; set; }
public MainWindow()
{
InitializeComponent();
FirstString = "First";
SecondString = "Second";
ThirdString = "Third";
FourthString= "Fourth";
this.DataContext = this; //here you set the context to current instance of window
}