所以我正在编写一个应用程序,它(现在)有一个用户控件,我正在对其他一些元素进行分组。我想在用户控件中的属性更改时更新视图。我试图实现Inotify,它似乎有效(我在主要形式中以相同的方式完成它,那里很好)。还试图在XAML中设置绑定但不能以某种方式通过它。我猜我必须实现一个路由事件,但我不确定在这种情况下是否以及如何。
我注意到我可以从OnPropertyChanged方法中删除一些内容,但如果我想删除现在未分配的相应事件,则表明我没有实现INotify。
来自用户控件的XAML:
<UserControl x:Class="Tool_WPF.frmLogin"
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:Fever_Tool_WPF"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel>
<Label Name="labLogin" HorizontalAlignment="Center" MaxWidth="150">
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=LoginState, ElementName=labLogin}" Value="1">
<Setter Property="Label.Content" Value="Success"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label>
<Label HorizontalAlignment="Center">Forum username</Label>
<TextBox x:Name="tbUser" Width="150"></TextBox>
<Label HorizontalAlignment="Center">Forum password</Label>
<PasswordBox x:Name="tbPassword" Width="150"></PasswordBox>
<Button x:Name="cmdLogin" HorizontalAlignment="Center" Margin="10" Width="150" Click="cmdLogin_Click">Login</Button>
</StackPanel>
</Grid>
用户控件(属性类)的代码背后
public class StateLogin : INotifyPropertyChanged
{
private int _loginState; // helping variable to trigger login state change
public event PropertyChangedEventHandler PropertyChanged;
public int LoginState
{
get { return _loginState; }
set
{
_loginState = value;
OnPropertyChanged("LoginState");
}
}
protected void OnPropertyChanged(string name)
{
new PropertyChangedEventArgs(name);
}
}
一些主窗口XAML代码
<RibbonWindow
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:Fever_Tool_WPF"
xmlns:Primitives="clr-namespace:System.Windows.Controls.Ribbon.Primitives;assembly=System.Windows.Controls.Ribbon" x:Class="Fever_Tool_WPF.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="589" Width="896"
Initialized="MainWindow_Initialized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Ribbon x:Name="ribbonMain">
<Ribbon.HelpPaneContent>
<RibbonButton SmallImageSource="Icons/MainWindow/help.ico"/>
</Ribbon.HelpPaneContent>
<Ribbon.QuickAccessToolBar>
<RibbonQuickAccessToolBar/>
</Ribbon.QuickAccessToolBar>
<Ribbon.ApplicationMenu>
<RibbonApplicationMenu SmallImageSource="Icons/MainWindow/BlogHomePage.ico">
<RibbonApplicationMenuItem Header="Information" ImageSource="Icons/MainWindow/Info.ico" Click="RibInfo_Click"/>
</RibbonApplicationMenu>
</Ribbon.ApplicationMenu>
<RibbonTab x:Name="rLogin" Header="Login" Visibility="Visible"/>
<RibbonTab x:Name="rMPL" Header="MPL"/>
</Ribbon>
<local:frmLogin x:Name="frmLogin" Margin="10, 10, 10, 10" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1" Visibility="Visible"/>
<StatusBar DockPanel.Dock="Bottom" MinHeight="10" MaxHeight="20" Grid.Row="2">
<StatusBarItem DockPanel.Dock="Right">
<Image>
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Ping}" Value="false">
<Setter Property="Image.Source" Value="Icons/MainWindow/StatusOffline_stop_32x.png"/>
<Setter Property="Image.ToolTip" Value="Can't ping the server."/>
</DataTrigger>
<DataTrigger Binding="{Binding Ping}" Value="true">
<Setter Property="Image.Source" Value="Icons/MainWindow/StatusOK_32x.png"/>
<Setter Property="Image.ToolTip" Value="Successfully pinged the server."/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StatusBarItem>
</StatusBar>
</Grid>
如上所述,我想我在路由上有点遗漏(根本没有路由^^),有人对此有所了解吗?
答案 0 :(得分:0)
将您的StateLogin
- 班级更改为
public class StateLogin : INotifyPropertyChanged
{
private int _loginState; // helping variable to trigger login state change
public event PropertyChangedEventHandler PropertyChanged;
public int LoginState
{
get { return _loginState; }
set
{
_loginState = value;
OnPropertyChanged("LoginState");
}
}
protected void OnPropertyChanged(string name)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
你必须告诉你的事件,它应该实际发射。
修改强>
假设您的DataContext和其他所有内容都设置正确,您应该尝试使用UserControl:
<UserControl x:Class="Tool_WPF.frmLogin"
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"
x:Name="LoginRoot"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel>
<TextBlock Name="labLogin" HorizontalAlignment="Center" MaxWidth="150">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=LoginRoot, Path=DataContext.LoginState}" Value="1">
<Setter Property="Text" Value="Success"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Label HorizontalAlignment="Center">Forum username</Label>
<TextBox x:Name="tbUser" Width="150"></TextBox>
<Label HorizontalAlignment="Center">Forum password</Label>
<PasswordBox x:Name="tbPassword" Width="150"></PasswordBox>
<Button x:Name="cmdLogin" HorizontalAlignment="Center" Margin="10" Width="150" Click="cmdLogin_Click">Login</Button>
</StackPanel>
</Grid>
</UserControl>
不需要标签,因为您只使用一些文字。 另外,我建议您深入了解XAML的工作原理。将样式作为内容放置永远不是一个好主意。
希望这会让你更进一步。干杯