如何在 WPF C# 中将字符串绑定到标签内容?

问题描述 投票:0回答:2

我目前正在做一个项目,我主要关注后端,我知道这个 XAML 代码不是好的做法。我不太习惯 INotifyPropertyChanged 接口,而且我真的很难看到错误。当我调试程序时,TourName 不为空,它从 liveTourAppointment.tour.name 获取值;但是当我运行它时窗口中的标签保持为空

这是我尝试过的:

XAML代码:


    <Grid>
        
        <Label x:Name ="Label" Content="{Binding Path=TourName}" Margin="82,44,579,354"/>

    </Grid>
</Window>

后面的代码在这里:

    public partial class LiveTourWin : Window, INotifyPropertyChanged
    {
        public TourAppointment liveTourAppointment { get; set; }
        
        private string _tourName =".";
        public string TourName
        {
            get { return _tourName; }
            set
            {
                {
                    if (value != _tourName)
                    {
                        _tourName = value;
                        OnPropertyChanged(nameof(TourName));
                    }
                }
            }
        }

        private readonly TourAppointmentController _tourAppointmentController;
        public LiveTourWin(int guideId)
        {
            InitializeComponent();
            this.DataContext = this;

            _tourAppointmentController = new TourAppointmentController();
            

            liveTourAppointment = _tourAppointmentController.GetLiveTour(guideId);
            this.TourName = liveTourAppointment.tour.name;
            
        }

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler? PropertyChanged;
    }
}

c# .net wpf binding
2个回答
0
投票

嘿,GPT-4 完全做到了,所以不要指望它会起作用:

看起来您正在 LiveTourWin 类的构造函数中设置 TourName 的值,但您没有引发 PropertyChanged 事件来通知 UI 该值已更改。

要解决此问题,您可以在 TourName 属性的 set 方法中引发 PropertyChanged 事件,如下所示:

private string _tourName = ".";
public string TourName
{
    get { return _tourName; }
    set
    {
        if (value != _tourName)
        {
            _tourName = value;
            OnPropertyChanged(nameof(TourName));
        }
    }
}

然后在 LiveTourWin 类的构造函数中,您可以像这样设置 TourName 属性:

liveTourAppointment = _tourAppointmentController.GetLiveTour(guideId);
TourName = liveTourAppointment.tour.name;

这样,当 TourName 属性被设置时,将引发 PropertyChanged 事件,并通知 UI 更新标签的内容。

此外,值得注意的是,在您的 XAML 代码中,您绑定到 TourName 属性,但没有为标签指定 DataContext。在您的构造函数中,您将窗口的 DataContext 设置为此,这意味着标签将从窗口继承 DataContext,因此将找到 TourName 属性。因此,对于这种特殊情况,您无需在 XAML 代码中执行任何其他操作。


0
投票

您的绑定已找到。你的问题是边距。您正在做一些绝对设置。尽量不要那样做。 “窗口”中的每个对象(例如您的网格对象)都会占用整个可用空间。很像浏览器。您调整窗口大小,通常会自动调整列等。

为此,请在窗口中分配空间并自动调整以允许收缩/扩展。现在,怎么做。

<Grid>
    <!-- Example of 3 equally sized columns -->
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <!-- multiple rows with different fixed heights.
         The last row with "*" means take up all unused space for the rest -->
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="28" />
        <RowDefinition Height="28" />
        <RowDefinition Height="100" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <!-- Place whatever controls at specific row/column locations -->
    <Label Grid.Row="3" Grid.Column="2" (rest of label content />
</Grid>

此外,您可以分配最小尺寸加上“”以允许基于可用的拉伸,如下所示。这有 3 列。第一列固定为 120 像素,但其余两列具有预定义的最小值,但由于“”在两列上,因此它们可以根据可用情况拉伸或收缩。所以,假设窗口是 800 宽。第一个仍然是 120,第二个和第三个分别得到 200 和 350,总共 670,还剩下 130。由于两列有“*”,每列的宽度将增加 65。这同样适用于行定义。

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="120" />
    <ColumnDefinition Width="200*" />
    <ColumnDefinition Width="350*" />
</Grid.ColumnDefinitions>

还有其他类型的控件、StackPanel、DockPanel 等允许其他格式和对齐选项。

所以,您的绑定有效,但是如果您给它一个预先分配空间的指定位置,因为您最终将准备您的用户界面,制作适合您的东西,而不用担心“固定”边距等。

附加说明,对于标签,因为它们通常预先生成一次,您可能需要添加到绑定子句中,例如

 <Label x:Name ="Label" Content="{Binding Path=TourName, NotifyOnSourceUpdated=True}" />
© www.soinside.com 2019 - 2024. All rights reserved.