You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# MVVM模式下DialogBox绑定Model数据无显示问题求助

问题:DialogBox中无法绑定显示Prestage.ServerName数据

在MVVM模式下,尝试将M_Prestage模型的ServerName数据绑定到DialogBox内TextBlock的Text属性,但文本未显示。相同绑定逻辑在UserControl中可正常工作,且日志能正常输出Prestage.ServerName的值。

相关代码

ViewModel(VM_WizardPrestage)

LogEvents.Add("Server Name : " + Prestage.ServerName);
var dialog = new DialogBox(); // 原始代码
//var dialog = new DialogBox { DataContext = Prestage }; // Clemens的建议,需结合构造函数或XAML测试

bool? result = dialog.ShowDialog();

Model(M_Prestage)

public class M_Prestage
{
    public string ServerName { get; set; }
    // 其他代码...
}

DialogBox构造函数

public DialogBox()
{
    // 此处应如何处理?
    InitializeComponent();
}

View(DialogBox.xaml)

<Window x:Class="PRESTAGE.Views.DialogBox"
        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:local="clr-namespace:PRESTAGE.Views"
        mc:Ignorable="d"
        Title="DialogBox" Height="150" Width="400" WindowStyle="None" WindowStartupLocation="CenterScreen" Background="Transparent" ResizeMode="NoResize" MouseDown="Window_MouseDown" AllowsTransparency="True">
    <Window.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="IsEnabled" Value="True"/>
            <Setter Property="Background" Value="#FFECE1E1"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="#FF022A79"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    
    <Grid>
        <Border  CornerRadius="12" BorderThickness="2" BorderBrush="#FF022A79">
            <Border.Background>
                <ImageBrush ImageSource="/Images/banner_prestage.png"
                            Stretch="Uniform" Opacity="1"/>
            </Border.Background>
            <Border CornerRadius="10"                    
                    BorderThickness="0"
                    Opacity="0.95">
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,1" EndPoint="0,5">
                        <GradientStop Color="White" Offset="0"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
                <StackPanel >
                    <StackPanel Margin="0,20,0,0">
                        <TextBlock Text="Would you like to change the server name?" HorizontalAlignment="Center" Foreground="#FF022A79"></TextBlock>
                    </StackPanel>
                    <StackPanel Margin="0,20,0,0">
                        <TextBlock Text="{Binding Path=Prestage.ServerName, NotifyOnTargetUpdated=True}" HorizontalAlignment="Center" Foreground="#FF022A79"></TextBlock>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Height="48" Margin="0,20,0,0">
                        <StackPanel VerticalAlignment="Center" Width="242">
                            <Button x:Name="Oui" Width="226" Height="30" Content="OUI" HorizontalAlignment="Right" Cursor="Hand" Margin="0,0,9,0" Click="Oui_Click">
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border Width="73" Height="30" CornerRadius="10"  Background="{TemplateBinding Background}">
                                            <ContentPresenter   VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                        </Border>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>
                        </StackPanel>
                        <StackPanel Orientation="Horizontal" Width="158">
                            <Button x:Name="Non" Width="73" Height="30" Content="NON" HorizontalAlignment="Right" Cursor="Hand" VerticalAlignment="Center" Click="Non_Click">
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border Width="73" Height="30" CornerRadius="10"  Background="{TemplateBinding Background}">
                                            <ContentPresenter   VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                        </Border>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>
                        </StackPanel>
                    </StackPanel>
                </StackPanel>
            </Border>
        </Border>
    </Grid>
</Window>

解决方案

问题核心是DataContext设置与绑定路径不匹配,导致绑定无法找到目标属性。以下是两种可行方案:

方案一:将DialogBox的DataContext设为ViewModel实例

如果希望保留原绑定路径Prestage.ServerName,需将DialogBox的DataContext指向VM_WizardPrestage实例(即ViewModel本身):

// 在VM_WizardPrestage中修改Dialog初始化代码
var dialog = new DialogBox { DataContext = this }; // this代表当前ViewModel实例
bool? result = dialog.ShowDialog();

XAML中的绑定无需修改,保持原样:

<TextBlock Text="{Binding Path=Prestage.ServerName, NotifyOnTargetUpdated=True}" ... />

方案二:将DialogBox的DataContext设为Prestage实例并修改绑定路径

若直接将Prestage实例作为DialogBox的DataContext,需调整绑定路径为ServerName(因为此时DataContext就是Prestage对象):

// 在VM_WizardPrestage中修改Dialog初始化代码
var dialog = new DialogBox { DataContext = Prestage };
bool? result = dialog.ShowDialog();

修改XAML中的绑定路径:

<TextBlock Text="{Binding Path=ServerName, NotifyOnTargetUpdated=True}" HorizontalAlignment="Center" Foreground="#FF022A79"></TextBlock>

额外优化:实现INotifyPropertyChanged(可选)

当前M_Prestage未实现INotifyPropertyChanged接口,若后续ServerName是动态更新的,UI不会自动同步刷新。建议给模型添加该接口:

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class M_Prestage : INotifyPropertyChanged
{
    private string _serverName;
    public string ServerName
    {
        get => _serverName;
        set
        {
            if (_serverName != value)
            {
                _serverName = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

    // 其他代码...
}

内容的提问来源于stack exchange,提问作者jeheel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:38:14