【问题标题】:Error in data binding in XamlXaml 中的数据绑定错误
【发布时间】:2017-03-31 11:00:40
【问题描述】:
I have tried data binding in WPF.
But it is showing few errors.Please help me.

我正在附加代码。我创建了一个简单的文本块并尝试绑定字符串。我还想知道 Windows.datacontext 是如何工作的?在我的代码中,它给出了一个错误。请帮帮我。

Xaml code
<Window x:Class="Shweta.DataBinding"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataBinding" Height="300" Width="300">
    <Window.DataContext>
        <l:DataBinding />
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="54*" />
            <ColumnDefinition Width="224*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="59*" />
            <RowDefinition Height="202*" />
        </Grid.RowDefinitions>
        <Grid Grid.Column="1" Grid.Row="1">
            <TextBlock Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" Text="{Binding TextString, TargetNullValue=Test}" VerticalAlignment="Top" Width="68" />
        </Grid>
    </Grid>
</Window>

**Code behind**

namespace Shweta
{
    public partial class DataBinding : Window
    {
        public DataBinding()
        {
            InitializeComponent();
            Setupviewmodel();
        }
        private void Setupviewmodel
        {
            TextString="this worked";
        }
        public string TextString{get;set;}
    }
}

【问题讨论】:

  • “很少有错误”? 什么错误?
  • 错误 1 ​​需要获取或设置访问器 错误 2 ''l' 是未声明的前缀。第 6 行,第 10 位。 XML 无效。错误 3 当前上下文中不存在名称“Setupviewmodel”
  • 错别字:Setupviewmodel 之后您缺少 ()
  • 谢谢。 () 被添加。第二个错误没有得到解决。错误 2 ''l' 是一个未声明的前缀。第 6 行,第 10 位。 XML 无效。

标签: c# wpf


【解决方案1】:

好的,首先阅读错误消息...它清楚地表明l 未在XAML 中定义,但您仍在尝试使用它:&lt;l:DataBinding /&gt;...

通过在 XAML 中声明 l 来解决此问题:

<Window x:Class="Shweta.DataBinding"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:l="<your l declaration"/>

另一件事是你还没有实现INotifyPropertyChanged,所以你的值无论如何都不会更新。

这样实现:

public partial class DataBinding : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    void NotifyPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if ( PropertyChanged != null )
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    string text;
    public string TextString
    {
        get { return text; }
        set { text = value; NotifyPropertyChanged(); }
    }

    public DataBinding()
        : base()
    {
        InitializeComponent();
        Setupviewmodel();
        // as @Nahuel Ianni stated, he has to set DataContext to CodeBehind
        // in order to be able to get bindings work 
        DataContext = this; // <-- only if not binded before
    }

    public void Setupviewmodel() // forgot to to place () 
    // produced error : `A get or set accessor expected`
    {
        TextString = "this worked";
    }
}

还有一件事是你必须指定 DataContext 只有当它与你的代码不同时才需要这部分:

<Window.DataContext>
    <l:DataBinding />
</Window.DataContext>

【讨论】:

    【解决方案2】:

    您没有正确指定 DataContext,因为您尝试使用尚未声明的命名空间在 XAML 上设置它。有关 XAML 命名空间的更多信息,请查看following link

    在您的示例中,它将位于 xaml 方面:

    <Window x:Class="Shweta.DataBinding"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="DataBinding" Height="300" Width="300">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="54*" />
                <ColumnDefinition Width="224*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="59*" />
                <RowDefinition Height="202*" />
            </Grid.RowDefinitions>
            <Grid Grid.Column="1" Grid.Row="1">
                <TextBlock Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" Text="{Binding TextString, TargetNullValue=Test}" VerticalAlignment="Top" Width="68" />
            </Grid>
        </Grid>
    </Window>
    

    在你的代码后面:

    namespace Shweta
    {
        public partial class DataBinding : Window
        {
            public DataBinding()
            {
                InitializeComponent();
                this.DataContext = this;  // Pay attention to this line!
                Setupviewmodel();
            }
    
            private void Setupviewmodel()
            {
                TextString="this worked";
            }
    
            public string TextString{get;set;}
        }
    }
    

    与原始版本的不同之处在于我没有在 XAML 上指定 DataContext,而是在其背后的代码上指定。

    DataContext 可以被认为是视图从中检索信息的地方。如有疑问,请参阅此MSDN article,或者您可以了解MVVM pattern,它是使用 XAML 的支柱。

    【讨论】:

    • 如果DataContextCodeBehind不是同一个对象,你只需要改变它。另外,您还没有使用过INotifyPropertyChanged,所以TextBlock 的值不会更新。
    • @m.rogalski 接口注释是正确的,虽然不是用户说明的问题的一部分,但需要将 DataContext 设置为自身(或其他对象),否则将无法正常工作.在我提出的代码中,即使是第一次绑定也会起作用。
    • 我不必将DataContext 设置为任何东西,它就可以工作。我认为这可能取决于框架本身。这可能是合理的
    • @m.rogalski 不能在那里争论。在我的本地项目中,当我尝试时;没有这个声明就没有任何约束力。
    • 这是值得了解的。谢谢你的提示。现在我知道有时这可能会导致绑定问题:)
    【解决方案3】:

    为了完成这项工作,您必须正确设置DataContext。我建议创建一个视图模型类并绑定到它。此外,我在代码隐藏中初始化了绑定,因为您的命名空间丢失了。您也可以在 xaml 中执行此操作。现在为您提供一些可以使用的东西,试试这个为您的代码隐藏:

    public partial class DataBinding : Window
    {
      public DataBinding()
      {
        InitializeComponent();
        DataContext = new DataBindingViewModel();
      }
    }
    
    public class DataBindingViewModel
    {
      public DataBindingViewModel()
      {
        Setupviewmodel();
      }
      private void Setupviewmodel()
      {
        TextString = "this worked";
      }
      public string TextString { get; set; }
    }
    

    然后改变你的观点:

    <Window x:Class="Shweta.DataBinding"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataBinding" Height="300" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="54*" />
            <ColumnDefinition Width="224*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="59*" />
            <RowDefinition Height="202*" />
        </Grid.RowDefinitions>
        <Grid Grid.Column="1" Grid.Row="1">
            <TextBlock Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" Text="{Binding TextString, TargetNullValue=Test}" VerticalAlignment="Top" Width="68" />
        </Grid>
    </Grid>
    

    请注意,Text 属性只会在初始化时设置。如果您希望在运行时使用 DataBinding,您的 DataBindingViewModel 将必须实现 INPC 并在设置属性绑定后抛出 PropertyChanged 事件。

    【讨论】:

    • 在 XAML 中的绑定不需要创建一个新类作为 ViewModel,他可以使用后面的代码来毫无问题地绑定值。
    • @NahuelIanni 您还可以在一个 .cs 文件中包含十亿个类,或者将所有代码写在一行中。
    • 确实可以,但是您在其中混合了问题。没有额外的课程并不是他遇到问题的原因。这只是一种不同的模式(或缺乏)。问题出在其他地方。
    • @NahuelIanni Ofc 这不是问题,为什么程序无法运行。这就是为什么我也解决了 DataContext 问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2015-11-23
    • 2012-11-14
    相关资源
    最近更新 更多