我是WPF的新手,并且面临有关绑定的问题。
我有一个MainWindow
和一个Rectangle
,使用绑定来更改视觉属性。 XAML代码如下:
<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
内,我使用StackPanel
来加载不同的UserControl
(MainWindow
充当标题)。
我关心的是UserControl
的绑定; BddState值会相应更改,但是MainWindow
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矩形无效
这里是安迪(Andy)示例之后的一些更新(可能会有所帮助) 通过强制转换mainwindow datacontext:
MainWindowViewModel viewModel = App.Current.MainWindow.DataContext as MainWindowViewModel;
if (viewModel != null)
{
viewModel.BddState = true;
}
答案 0 :(得分:1)
我将您的标记修改为:
<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”表示您的矩形不在窗口内。
您的图像路径不起作用。
均匀拉伸会造成问题,矩形中没有图片的部分不在屏幕上。
然后我进一步修改了它,以最初通过viewmodel中的私有后备字段将bddstate设置为true。添加了一个ischecked绑定到bddstate的切换按钮。 可以成功在黄色和绿色之间切换。
这是一个涉及用户控件的有效版本。我已经从测试样本中的BaseViewModel继承了MainWindowViewModel。
MainWindow:
<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");
}
}
UserControl1
<ToggleButton Width="100" Height="30" Content="Toggle" IsChecked="{Binding BddState, Mode=TwoWay}"/>
BaseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
没有任何代码。
这仍然有效。