我试图从我的主UserControl中控制子UserControls的状态。我正在考虑通过在父UC中创建DependencyProperty对象并在创建子UC时在XAML中引用该对象来实现这一目标。
问题是,我在Step.xaml.cs中获得了NullReferenceException(后面的子代码),所有内容都引用了Controller属性,首先是StepEnabled属性。当我省掉XAML绑定并让它在构造函数中实例化时,就可以了,尽管我当然不能控制任何东西,但是它的Controller属性始终为null ...代码如下:
ParentViewModel:
public class ParentVM : NotifyPropChanged
{
...
public StepController Step1 = new StepController();
public StepController Step2 = new StepController();
public StepController Step3 = new StepController();
public ParentVM()
{
...
GetReady();
}
public void GetReady()
{
Step1.Clear();
Step2.Clear();
Step3.Clear();
}
StepController:
public class StepController
{
public bool StepEnabled;
public bool? WasSuccessful;
public StepController()
{
Clear();
}
public void Clear()
{
StepEnabled = false;
WasSuccessful = null;
}
}
子代(后面的代码):
public partial class Step : UserControl
{
public static DependencyProperty ControllerProperty =
DependencyProperty.Register("Controller", typeof(StepController), typeof(Step), new UIPropertyMetadata(null));
public StepController Controller
{
get { return (StepController)GetValue(ControllerProperty); }
set { SetValue(ControllerProperty, value); }
}
...
public bool StepEnabled
{
get { return (bool)Controller.StepEnabled; }
set { Controller.StepEnabled = value; }
}
public bool IsDone
{
get
{
return (Controller.WasSuccessful != null);
}
}
public bool? WasSuccessful
{
get { return Controller.WasSuccessful; }
set { Controller.WasSuccessful = value; }
}
public Step()
{
InitializeComponent();
this.DataContext = this;
...
Controller = new StepController();
}
}
ParentUC:
...
<local:Step Controller="{Binding Path=Step1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
...
ChildUC:
e.g.:
<TextBlock IsEnabled="{Binding StepEnabled, UpdateSourceTrigger=PropertyChanged}" />
我对WPF还是很陌生,仍然不确定诸如DataContext之类的很多东西,所以我想我缺少明显的东西了……感谢您的提前帮助!
就像@Synapse已经提到您的DependencyProperty
内部一样Step
-UserControl
应该为您的StepController
课程实例化默认值:
public static readonly DependencyProperty ControllerProperty = DependencyProperty.Register(
"Controller", typeof (StepController), typeof (Step), new PropertyMetadata(default(StepController)));
public StepController Controller
{
get { return (StepController) GetValue(ControllerProperty); }
set { SetValue(ControllerProperty, value); }
}
您的ParentUC应该看起来像这样(例如,仅在此处设置DataContext):
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:StepControllerExample" x:Class="StepControllerExample.ParentUserControl"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<local:ParentVM/>
</UserControl.DataContext>
<StackPanel HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100">
<local:Step Controller="{Binding Step1}"/>
<local:Step Controller="{Binding Step2}"/>
<local:Step Controller="{Binding Step3}"/>
</StackPanel>
您的子级UserControl XAML如下所示:
<UserControl x:Name="userControl" x:Class="StepControllerExample.Step"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Vertical" d:LayoutOverrides="Height">
<TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="TextBlock"/>
<CheckBox x:Name="checkBox" Content="CheckBox" IsChecked="{Binding Controller.StepEnabled, ElementName=userControl}"/>
</StackPanel>
您的孩子的UserControl代码背后是这样的:
public partial class Step : UserControl
{
public Step()
{
InitializeComponent();
}
public static readonly DependencyProperty ControllerProperty = DependencyProperty.Register(
"Controller", typeof (StepController), typeof (Step), new PropertyMetadata(default(StepController)));
public StepController Controller
{
get { return (StepController) GetValue(ControllerProperty); }
set { SetValue(ControllerProperty, value); }
}
}
和你这样的StepController
班级:
public class StepController : INotifyPropertyChanged
{
private bool _stepEnabled;
private bool? _wasSuccessful;
public StepController()
{
Clear();
}
public bool StepEnabled
{
get { return _stepEnabled; }
set
{
if (value == _stepEnabled) return;
_stepEnabled = value;
OnPropertyChanged();
}
}
public bool? WasSuccessful
{
get { return _wasSuccessful; }
set
{
if (value == _wasSuccessful) return;
_wasSuccessful = value;
OnPropertyChanged();
}
}
public void Clear()
{
StepEnabled = false;
WasSuccessful = null;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句