WPF 绑定不更新可见性
WPF Binding not updating Visibility
我在绑定到网格的可见性时遇到问题。我有过我以前做过的项目,并试图复制以前使用的相同编码,我四处搜索并根据其他一些文章将 bool 添加到可见性转换器中,但仍然一无所获。
到目前为止,我在这个项目中尝试做的就是为用户提供一组选项。当他们 select 一个选项时,它会显示子选项或将它们带到适当的区域。我将绑定设置为一个 bool 对象,有时会创建一些小消息框和其他消息框,只是为了让我知道程序是否到达任何地方。我一路上得到了每个消息框,所以它似乎到达了每一段代码。
任何人都可以阐明我做错了什么或指出正确的方向吗?
Windows.Resources 中的转换器(已编辑以显示 Windows.Resources 中的所有代码)
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Height" Value="50" />
<Setter Property="Width" Value="100" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
其余代码在window
<Grid>
<Grid x:Name="grid_mainMenu" Visibility="{Binding MainMenuVisibility, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Button x:Name="button_Items" Content="Items" Grid.Row="0" Click="button_Items_Click"/>
<Button x:Name="button_Orders" Content="Orders" Grid.Row="1" Click="button_Orders_Click" />
<TextBox Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Height="100" Width="100"/>
</Grid>
<Grid x:Name="grid_itemMenu" Visibility="{Binding ItemMenuVisibility, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Content="Item Menu" Grid.Row="0" FontSize="20" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Grid.Row="1" x:Name="button_itemMaintenance" Content="Maintenance"/>
<Button Grid.Row="2" x:Name="button_itemCreation" Content="Create"/>
</Grid>
<DockPanel Height="25" Margin="0,0,0,0" VerticalAlignment="Bottom">
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StatusBarItem>
</StatusBar>
</DockPanel>
</Grid>
这是class
中的代码
public bool MainMenuVisibility
{
get { return _mainMenuVisibility; }
set { _mainMenuVisibility = value; RaisePropertyChanged(); }
}
public bool ItemMenuVisibility
{
get { return _itemMenuVisibility; }
set
{ _itemMenuVisibility = value; RaisePropertyChanged(); }
}
public bool OrderMenuVisibility
{
get { return _orderMenuVisibility; }
set { _orderMenuVisibility = value; RaisePropertyChanged(); }
}
主要构造函数
public Menu_View()
{
ShowMainMenu();
}
几个控件
public void ShowMainMenu()
{
MainMenuVisibility = true;
HideItemMenu();
HideOrderMenu();
StatusMessage = "Showing main menu";
}
public void HideMainMenu()
{
MainMenuVisibility = false;
StatusMessage = "Hid main menu";
}
public void ShowItemMenu()
{
try
{
//Reaches, but never updates
ItemMenuVisibility = true;
HideMainMenu();
HideOrderMenu();
}
catch(Exception error)
{
//Never shows anything here
StatusMessage = "Failed to load item menu";
}
finally
{
//Does not update, but reaches here
StatusMessage = "Showing item menu";
}
}
程序从显示主菜单开始,当用户单击项目按钮时,它应该显示项目菜单。单击按钮调用 ShowItemMenu()。我已经验证确实发生了这种情况并且以正确的顺序被调用。
我已验证 ShowItemMenu() 确实有效,但放入了构造函数而不是 ShowMainMenu()。任何一个都可以正常工作,但即使在按下按钮后到达它们,也不会在初始加载后导致更新。
抱歉,如果我没有包括我需要的一切。
编辑:
我相信我实际上同时遇到了两个问题。一个是配置不当的数据转换器。回答和参考如下。
以及我的 window 代码中的一个问题:
public MainWindow()
{
InitializeComponent();
menuView = new Menu_View();
this.DataContext = new Menu_View();
}
Menu_View menuView;
我认为这是问题的一部分。我正在创建 Menu_View 类型的 menuView。在初始化时,我将 menuView 分配给一个新的 Menu_View(),然后将我的 DataContext 分配给一个新的 Menu_View() 而不是 menuView。所有命令都在更新 menuView,而我正在更新分配给 DataContext 的命令。
将此 converter
class 添加到您的项目中。
class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Boolean && (bool)value)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Visibility && (Visibility)value == Visibility.Visible)
{
return true;
}
return false;
}
}
Referance
如果您愿意,可以不使用布尔转换器。您不必编写任何代码隐藏。
<Grid>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=MyBoolValue}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
我在绑定到网格的可见性时遇到问题。我有过我以前做过的项目,并试图复制以前使用的相同编码,我四处搜索并根据其他一些文章将 bool 添加到可见性转换器中,但仍然一无所获。
到目前为止,我在这个项目中尝试做的就是为用户提供一组选项。当他们 select 一个选项时,它会显示子选项或将它们带到适当的区域。我将绑定设置为一个 bool 对象,有时会创建一些小消息框和其他消息框,只是为了让我知道程序是否到达任何地方。我一路上得到了每个消息框,所以它似乎到达了每一段代码。
任何人都可以阐明我做错了什么或指出正确的方向吗?
Windows.Resources 中的转换器(已编辑以显示 Windows.Resources 中的所有代码)
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Height" Value="50" />
<Setter Property="Width" Value="100" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
其余代码在window
<Grid>
<Grid x:Name="grid_mainMenu" Visibility="{Binding MainMenuVisibility, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Button x:Name="button_Items" Content="Items" Grid.Row="0" Click="button_Items_Click"/>
<Button x:Name="button_Orders" Content="Orders" Grid.Row="1" Click="button_Orders_Click" />
<TextBox Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Height="100" Width="100"/>
</Grid>
<Grid x:Name="grid_itemMenu" Visibility="{Binding ItemMenuVisibility, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Content="Item Menu" Grid.Row="0" FontSize="20" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Grid.Row="1" x:Name="button_itemMaintenance" Content="Maintenance"/>
<Button Grid.Row="2" x:Name="button_itemCreation" Content="Create"/>
</Grid>
<DockPanel Height="25" Margin="0,0,0,0" VerticalAlignment="Bottom">
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StatusBarItem>
</StatusBar>
</DockPanel>
</Grid>
这是class
中的代码 public bool MainMenuVisibility
{
get { return _mainMenuVisibility; }
set { _mainMenuVisibility = value; RaisePropertyChanged(); }
}
public bool ItemMenuVisibility
{
get { return _itemMenuVisibility; }
set
{ _itemMenuVisibility = value; RaisePropertyChanged(); }
}
public bool OrderMenuVisibility
{
get { return _orderMenuVisibility; }
set { _orderMenuVisibility = value; RaisePropertyChanged(); }
}
主要构造函数
public Menu_View()
{
ShowMainMenu();
}
几个控件
public void ShowMainMenu()
{
MainMenuVisibility = true;
HideItemMenu();
HideOrderMenu();
StatusMessage = "Showing main menu";
}
public void HideMainMenu()
{
MainMenuVisibility = false;
StatusMessage = "Hid main menu";
}
public void ShowItemMenu()
{
try
{
//Reaches, but never updates
ItemMenuVisibility = true;
HideMainMenu();
HideOrderMenu();
}
catch(Exception error)
{
//Never shows anything here
StatusMessage = "Failed to load item menu";
}
finally
{
//Does not update, but reaches here
StatusMessage = "Showing item menu";
}
}
程序从显示主菜单开始,当用户单击项目按钮时,它应该显示项目菜单。单击按钮调用 ShowItemMenu()。我已经验证确实发生了这种情况并且以正确的顺序被调用。
我已验证 ShowItemMenu() 确实有效,但放入了构造函数而不是 ShowMainMenu()。任何一个都可以正常工作,但即使在按下按钮后到达它们,也不会在初始加载后导致更新。
抱歉,如果我没有包括我需要的一切。
编辑:
我相信我实际上同时遇到了两个问题。一个是配置不当的数据转换器。回答和参考如下。
以及我的 window 代码中的一个问题:
public MainWindow()
{
InitializeComponent();
menuView = new Menu_View();
this.DataContext = new Menu_View();
}
Menu_View menuView;
我认为这是问题的一部分。我正在创建 Menu_View 类型的 menuView。在初始化时,我将 menuView 分配给一个新的 Menu_View(),然后将我的 DataContext 分配给一个新的 Menu_View() 而不是 menuView。所有命令都在更新 menuView,而我正在更新分配给 DataContext 的命令。
将此 converter
class 添加到您的项目中。
class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Boolean && (bool)value)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Visibility && (Visibility)value == Visibility.Visible)
{
return true;
}
return false;
}
}
Referance
如果您愿意,可以不使用布尔转换器。您不必编写任何代码隐藏。
<Grid>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=MyBoolValue}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>