如何正确将模型中的字符串绑定到 WPF 中的 TextBox?

huangapple go评论55阅读模式
英文:

How do I correctly bind a string in my model to an TextBox in WPF?

问题

我遇到了绑定错误,例如:

System.Windows.Data Error: 40 : BindingExpression 路径错误:在“object” “String” 上找不到“MyText”属性 (HashCode=-401799582)。 BindingExpression:Path=MyText; DataItem=“String” (HashCode=-401799582); 目标元素为“TextBox” (Name=“”); 目标属性为“Text” (类型“String”)

当尝试将我的模型的字符串属性绑定到TextBox和TextBlock时(上面的错误是TextBox的错误)。

我尝试松散地按照Microsoft网站上的 教程 进行操作。

在XAML中:

<Window x:Class="WpfApp1.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"
        xmlns:src="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <src:MyView x:Key="myView"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Label>Input:</Label>
            <TextBox>
                <TextBox.Text>
                    <Binding Source="{StaticResource myView}" Path="MyText" UpdateSourceTrigger="PropertyChanged"/>
                </TextBox.Text>
            </TextBox>
            <Label>In model:</Label>
            <TextBlock>
                <TextBlock.Text>
                    <Binding Source="{StaticResource myView}" Path="MyText"/>
                </TextBlock.Text>
            </TextBlock>
        </StackPanel>
    </Grid>
</Window>

在C#中:

using System.ComponentModel;
using System.Windows;

namespace WpfApp1
{
    public class MyView : INotifyPropertyChanged
    {
        public MyView() { }
        public event PropertyChangedEventHandler PropertyChanged;
        private string _myText;
        public string MyText
        {
            set
            {
                if (_myText != value)
                {
                    _myText = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyText"));
                }
            }
            get { return _myText;  }
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

我期望TextBlock在我在TextBox中输入文本时显示文本,但实际上没有任何反应(这是因为存在绑定错误)。我做错了什么?

英文:

I'm getting the binding errors, e.g.

> System.Windows.Data Error: 40 : BindingExpression path error: 'MyText' property not found on 'object' ''String' (HashCode=-401799582)'. BindingExpression:Path=MyText; DataItem='String' (HashCode=-401799582); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')

When trying to bind a string property of my model to a TextBox and a TextBlock (the error above is the one for the TextBox).

I've tried loosely following the how-to in Microsoft's site.

in xaml:


&lt;Window x:Class=&quot;WpfApp1.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        xmlns:src=&quot;clr-namespace:WpfApp1&quot;
        mc:Ignorable=&quot;d&quot;
        Title=&quot;MainWindow&quot; Height=&quot;450&quot; Width=&quot;800&quot;&gt;
    &lt;Window.Resources&gt;
        &lt;src:MyView x:Key=&quot;myView&quot;/&gt;
    &lt;/Window.Resources&gt;
    &lt;Grid&gt;
        &lt;StackPanel&gt;
            &lt;Label&gt;Input:&lt;/Label&gt;
            &lt;TextBox&gt;
                &lt;TextBox.Text&gt;
                    &lt;Binding Source=&quot;StaticResource myView&quot; Path=&quot;MyText&quot; UpdateSourceTrigger=&quot;PropertyChanged&quot;/&gt;
                &lt;/TextBox.Text&gt;
            &lt;/TextBox&gt;
            &lt;Label&gt;In model:&lt;/Label&gt;
                &lt;TextBlock&gt;
                &lt;TextBlock.Text&gt;
                    &lt;Binding Source=&quot;StaticResource myView&quot; Path=&quot;MyText&quot;/&gt;
                &lt;/TextBlock.Text&gt;
                &lt;/TextBlock&gt;
        &lt;/StackPanel&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;

in C#:


using System.ComponentModel;
using System.Windows;


namespace WpfApp1
{
    public class MyView : INotifyPropertyChanged
    {
        public MyView() { }
        public event PropertyChangedEventHandler PropertyChanged;
        private string _myText;
        public string MyText
        {
            set
            {
                if (_myText != value)
                {
                    _myText = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(&quot;MyText&quot;));
                }
            }
            get { return _myText;  }
        }

    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

I was expecting the TextBlock to display my text as I type it in the TextBox, but it runs and nothing happens (which makes sense seeing as there was a binding error).

What Am I doing wrong?

答案1

得分: 1

在字符串中编写StaticResource并不意味着您已引用该资源。StaticResource 是一个标记扩展,具有自己的语法(花括号):

<StackPanel>
    <Label>Input:</Label>
    <TextBox>
        <TextBox.Text>
            <Binding Source="{StaticResource myView}" Path="MyText" UpdateSourceTrigger="PropertyChanged"/>
        </TextBox.Text>
    </TextBox>

    <Label>In model:</Label>
    <TextBlock>
        <TextBlock.Text>
            <Binding Source="{StaticResource myView}" Path="MyText"/>
        </TextBlock.Text>
    </TextBlock>
</StackPanel>

您还可以以更简洁的方式编写相同的标记:

<StackPanel>
    <Label>Input:</Label>
    <TextBox Text="{Binding Path=MyText, Source={StaticResource myView}, UpdateSourceTrigger=PropertyChanged}"/>

    <Label>In model:</Label>
    <TextBlock Text="{Binding Path=MyText, Source={StaticResource myView}}"/>
</StackPanel>

或者甚至更好 - 声明 DataContext,而不是资源:

<Window x:Class="WpfApp1.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"
    xmlns:src="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <src:MyView />
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <Label>Input:</Label>
            <TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}"/>

            <Label>In model:</Label>
            <TextBlock Text="{Binding MyText}"/>
        </StackPanel>
    </Grid>
</Window>
英文:

writing StaticResource in a string doesn't mean that you referenced that resource. StaticResource is a markup extension and has its own syntax (curly braces):

&lt;StackPanel&gt;
    &lt;Label&gt;Input:&lt;/Label&gt;
    &lt;TextBox&gt;
        &lt;TextBox.Text&gt;
            &lt;Binding Source=&quot;{StaticResource myView}&quot; Path=&quot;MyText&quot; UpdateSourceTrigger=&quot;PropertyChanged&quot;/&gt;
        &lt;/TextBox.Text&gt;
    &lt;/TextBox&gt;

    &lt;Label&gt;In model:&lt;/Label&gt;
    &lt;TextBlock&gt;
        &lt;TextBlock.Text&gt;
            &lt;Binding Source=&quot;{StaticResource myView}&quot; Path=&quot;MyText&quot;/&gt;
        &lt;/TextBlock.Text&gt;
    &lt;/TextBlock&gt;
&lt;/StackPanel&gt;

you can also write the same markup in significantly less verbose way:

&lt;StackPanel&gt;
    &lt;Label&gt;Input:&lt;/Label&gt;
    &lt;TextBox Text=&quot;{Binding Path=MyText, Source={StaticResource myView}, UpdateSourceTrigger=PropertyChanged}&quot;/&gt;

    &lt;Label&gt;In model:&lt;/Label&gt;
    &lt;TextBlock Text=&quot;{Binding Path=MyText, Source={StaticResource myView}}&quot;/&gt;
&lt;/StackPanel&gt;

or even better - declare DataContext, not a Resource:

&lt;Window x:Class=&quot;WpfApp1.MainWindow&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    xmlns:src=&quot;clr-namespace:WpfApp1&quot;
    mc:Ignorable=&quot;d&quot;
    Title=&quot;MainWindow&quot; Height=&quot;450&quot; Width=&quot;800&quot;&gt;
    &lt;Window.DataContext&gt;
        &lt;src:MyView /&gt;
    &lt;/Window.DataContext&gt;
    &lt;Grid&gt;
        &lt;StackPanel&gt;
            &lt;Label&gt;Input:&lt;/Label&gt;
            &lt;TextBox Text=&quot;{Binding MyText, UpdateSourceTrigger=PropertyChanged}&quot;/&gt;
    
            &lt;Label&gt;In model:&lt;/Label&gt;
            &lt;TextBlock Text=&quot;{Binding MyText}&quot;/&gt;
         &lt;/StackPanel&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;

huangapple
  • 本文由 发表于 2023年2月19日 20:56:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500293.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定