首页 > 解决方案 > 来自 UserControl 的 WPF 绑定 MainWindow 控件,PropertyChanged 未触发

问题描述

我是 WPF 的新手,遇到了关于绑定的问题。我有一个使用绑定来更改视觉属性的MainWindowwith a 。RectangleXAML 代码如下:

<Rectangle Height="72" Canvas.Left="1011" RadiusY="6" RadiusX="6" StrokeThickness="2" Width="82" Canvas.Top="8">
    <Rectangle.Style>
        <Style TargetType="Rectangle">
            <Style.Triggers>
                <DataTrigger Binding="{Binding BddState}" Value="True">
                    <Setter Property="Fill">
                      <Setter.Value>
                        <ImageBrush ImageSource="Pictures/BDD_on.png" Stretch="Uniform" />
                      </Setter.Value>
                    </Setter>

                </DataTrigger>
                <DataTrigger Binding="{Binding BddState}" Value="False">
                    <Setter Property="Fill">
                        <Setter.Value>
                            <ImageBrush ImageSource="Pictures/Bdd_off.png" Stretch="Uniform" />
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Rectangle.Style>
</Rectangle>

我创建了一个视图模型类来管理绑定:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }


    private Boolean _bddstate;
    public Boolean BddState
    {
        get { return _bddstate; }
        set
        {
            _bddstate = value;
            OnPropertyChanged("BddState");
        }
    }
}

绑定在 MainWindow 中运行良好,使用:

private ViewModel _viewModel = new ViewModel();

public MainWindow()
{
    InitializeComponent();
    this.DataContext = _viewModel;
    _viewModel.BddState = true;        
}

在 内部MainWindow,我使用 aStackPanel来加载不同UserControl的(MainWindow充当标题)。我担心的是来自UserControl; MainWindowBddState 值会相应更改,但UI上没有任何反映。同时,我可以看到视图模型的处理程序总是null.

我究竟做错了什么?

预先感谢您的支持。

更新:这是用户控件的代码:

<Grid Background="#FFECECEC" Height="706" VerticalAlignment="Top">
    <Label x:Name="label" Content="HOME" HorizontalAlignment="Left" Margin="525,8,0,0" VerticalAlignment="Top" FontWeight="Bold" Foreground="{DynamicResource gray_2}" FontSize="20"/>
    <Label x:Name="label_Copy" Content="General Info" HorizontalAlignment="Left" Margin="441,34,0,0" VerticalAlignment="Top" Foreground="{DynamicResource gray_2}" FontSize="18"/>
    <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="441,214,0,0" VerticalAlignment="Top" Width="107" Height="36" Click="button_Click"/>


</Grid>

对于后面的代码,它只是以下内容:

 public partial class Home : UserControl
{
    public Home()
    {
        InitializeComponent();
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        ViewModel _vm = new ViewModel();
        _vm.BddState = true;
    }
}

当我单击 Home UC 的按钮时,ViewModel 的处理程序为 null,并且绑定在 MainWindow 矩形上无效

这里有一些更新跟随安迪的样本(它可以帮助),通过投射主窗口数据上下文它可以工作:

 MainWindowViewModel viewModel = App.Current.MainWindow.DataContext as MainWindowViewModel;
        if (viewModel != null)
        {
            viewModel.BddState = true;
        }

标签: wpfbinding

解决方案


我将您的标记修改为:

    <Canvas Name="MyCanvas" >
        <Rectangle Height="72"  RadiusY="6" RadiusX="6" StrokeThickness="2" Width="82" Canvas.Top="8">
            <Rectangle.Style>
                <Style TargetType="Rectangle">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding BddState}" Value="True">
                            <Setter Property="Fill" Value="Green"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding BddState}" Value="False">
                            <Setter Property="Fill" Value="Yellow"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Rectangle.Style>
        </Rectangle>
    </Canvas>

它不依赖任何图像,也没有 Canvas.Left。

我得到一个绿色矩形。

您什么都看不到的可能原因包括:

您的窗口比 1011px 窄,并且 Canvas.Left="1011" 表示您的矩形不在窗口内。

您的图像路径不起作用。

均匀拉伸会产生问题,其中包含任何图片的矩形部分不在屏幕上。

然后我进一步修改它,通过视图模型中的私有支持字段将 bddstate 设置为 true。添加了一个将 ischecked 绑定到 bddstate 的切换按钮。这成功地在黄色和绿色之间切换。

这是一个工作版本涉及一个用户控件。我从测试样本中的 BaseViewModel 继承了 MainWindowViewModel。

主窗口:

 <Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <Canvas Name="MyCanvas" >
        <Rectangle Height="72"  RadiusY="6" RadiusX="6" StrokeThickness="2" Width="82" Canvas.Top="8">
            <Rectangle.Style>
                <Style TargetType="Rectangle">
                    <Setter Property="Fill" Value="Green"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding BddState}" Value="False">
                            <Setter Property="Fill" Value="Yellow"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Rectangle.Style>
        </Rectangle>
    </Canvas>
    <local:UserControl1 Height="30" Width="100"/>
</Grid>

视图模型:

public class MainWindowViewModel : BaseViewModel
{
    private Boolean _bddstate = true;
    public Boolean BddState
    {
        get { return _bddstate; }
        set
        {
            _bddstate = value;
            RaisePropertyChanged("BddState");
        }
    }

用户控件1

    <ToggleButton Width="100" Height="30" Content="Toggle" IsChecked="{Binding BddState, Mode=TwoWay}"/>

基础视图模型

public  class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

后面没有代码。

这仍然有效。


推荐阅读