I am creating a C# WPF application. I have placed a Scrollviewer inside a grid cell. When the application is runnning, if I click anywhere inside the Scrollviewer cell, all of my toolbar buttons, which are located in a different cell and controlled by a different User Control suddenly get disabled and don't get re-enabled.
Why is this happening and how can I fix this?
Thanks for any help.
Here is my ScrollViewer code:
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Grid.Column="1" Grid.Row="1">
<StackPanel x:Name="innerPanel" Grid.Column="1"
Grid.Row="1" Orientation="Vertical">
</StackPanel>
</ScrollViewer>
And my ToolBar code:
<ToolBarTray Grid.Row="1" Grid.ColumnSpan="2" Background="LightGray" >
<ToolBar x:Name="toolbar" Background="LightGray" ToolBarTray.IsLocked="False">
<Button Command="New" Content="New" />
<Button Command="Open" Content="Open" />
<Button Command="Save" Content="Save" />
<Button Command="Cut" Content="Cut" />
<Button Command="Copy" Content="Copy" />
<Button Command="Paste" Content="Paste" />
<Button Command="Record" Content="Record" />
<Button Command="Play" Content="Play" />
<Button Command="Pause" Content="Pause" />
<Button Command="Stop" Content="Stop" />
<Image Width="20" Margin="5,0" Source="C:\VolumeIcon1.png"/>
<Slider x:Name="VolumeControl" Maximum="100" Width="250"
TickPlacement="BottomRight" Foreground="DarkGray"
TickFrequency="1" IsSnapToTickEnabled="True"/>
<TextBox Text="{Binding ElementName=VolumeControl, Path=Value,
UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Right"
TextAlignment="Right" Width="30"
</ToolBar>
</ToolBarTray>
Here are some images of the buttons when they are disabled vs enabled.
Edit: These four files should reproduce a basic version of the problem I am having. When the Scrollviewer area gets clicked, the new button in my toolbar gets disabled and grayed out.
MainWindow.xaml
<Window x:Class="UIMilestone.MainWindow" x:Name="window"
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:UIMilestone"
mc:Ignorable="d"
SizeChanged="OnWindowSizeChanged"
Title="MainWindow" Height="450" Width="800" Background="LightGray">
<Grid x:Name="mainGrid" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="row0" Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Grid.Column="1" Grid.Row="1">
</ScrollViewer>
</Grid>
MainWindow.xaml.cs
namespace UIMilestone
{
public partial class MainWindow : Window
{
//Links C# project to methods in c++
public MainWindow()
{
InitializeComponent();
mainGrid.Measure(new Size(800, 450));
mainGrid.Arrange(new Rect(0, 0, 800, 450));
TopToolbars tools = new TopToolbars(this);
mainGrid.Children.Add(tools);
}
protected void OnWindowSizeChanged(object sender, SizeChangedEventArgs e)
{
}
}
}
TopToolBars.xaml
<UserControl x:Class="UIMilestone.TopToolbars"
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:UIMilestone"
mc:Ignorable="d"
d:DesignHeight="47" d:DesignWidth="790">
<UserControl.CommandBindings>
<CommandBinding Command="New" CanExecute="New_CanExecute" />
</UserControl.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="327.333"/>
<ColumnDefinition Width="462.667"/>
</Grid.ColumnDefinitions>
<ToolBar x:Name="toolbar" Background="LightGray" ToolBarTray.IsLocked="False">
<Button Command="New" Content="New" />
</ToolBar>
</Grid>
TopToolBars.xaml.cs
using System.Windows.Controls;
using System.Windows.Input;
namespace UIMilestone
{
public partial class TopToolbars : UserControl
{
private MainWindow win;
public TopToolbars(MainWindow mainWindowInst)
{
win = mainWindowInst;
InitializeComponent();
this.SetValue(Grid.RowProperty, 0);
this.SetValue(Grid.ColumnProperty, 1);
}
private void New_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
}
}
That's because a routed command starts its journey at the element with the focus, bubbling up the visual tree. Your toolbar element is however not in the parent chain of the innerPanel.
Option 1: explicitly specify the toolbar element as command target: Add CommandTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TopToolbar}}" to your button
Option 2: put your command binding in the MainWindow.
Option 3: Use MVVM: create an ICommand property in your view model and Command="{Binding MyCommand}" in the button
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.