WPF Unleashed error? - wpf

The book says
The WPF Button class only adds two
simple concepts on top of what
ButtonBase already provides: being a
cancel button or a default button.
These two mechanisms are handy short-
cuts for dialogs. If Button.IsCancel
is setto true on a Button inside a
dialog (that is, a Window shown via
its ShowDialog method), the Window is
automatically closed with a
DialogResult of false. If
Button.IsDefault is set to true,
pressing Enter causes the Button to be
clicked unless focus is explicitly
taken away from it.
But in this sample window
<Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="About WPF Unleashed" SizeToContent="WidthAndHeight"
Background="OrangeRed" >
<StackPanel>
<Label FontWeight="Bold" FontSize="20" Foreground="White">
WPF Unleashed (Version 3.0)
</Label>
<Label> 2006 SAMS Publishing</Label>
<Label>Installed Chapters:</Label>
<ListBox>
<ListBoxItem>Chapter 1</ListBoxItem>
<ListBoxItem>Chapter 2</ListBoxItem>
</ListBox>
<TextBox AcceptsReturn="False">HELLO TEXT</TextBox>
<RadioButton>HELLO RADIO BUTTON</RadioButton>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button IsCancel="True" MinWidth="75" Margin="10">Cancel</Button>
<Button x:Name="OKBUTTON" IsDefault="True" MinWidth="75" Margin="10">OK</Button>
</StackPanel>
<StatusBar>You have successfully registered this product.</StatusBar>
</StackPanel>
</Window>
If I press Enter or even click it, the modal Window(By ShowDialog()) does not get closed (leave aside the return value).
Is that an error in the book ?

I believe it is an error. IsDefault and IsCancel simply means that some access-key-magic is applied when the window is created, so that the button is clicked when you hit 'Enter' and 'ESC' respectively.
If you want a Window to close - you need to:
(from MSDN )
When a dialog box is accepted, it should return a dialog box result of true, which is achieved by setting the DialogResult property when the OK button is clicked
...
Note that setting the DialogResult property also causes the window to close automatically, which alleviates the need to explicitly call Close.

Related

Button/Image Switch resource using click, MouseEnter and MouseLeave

I'm trying to change an image using events like Click, MouseEnter and MouseLeave. In first place I tried to do it with Buttons in order to have "Click" event too, but I don't know how to remove that lightblue background that appears by default when I put the mouse over the button with a png background.
After this, I tried to use , setting the resource image.png in its Source.
The main problem is that I don't know what to do in code-behind to change between Image Resources in order to change the Source of the control.
I want to know too if I can use a "Click Event" with an control
Update1:
Ok, I tried it by using Binding
For now I think its solved, but I have another problem.
I don't know exactly how to remove that "border". I tried to put the borderbrush property of the buttons to 0, but it seems to be another property or another control.
UI
Thanks.
You can put an image as the content of a button, and add an Click event to that Button. This way, an event gets called when you press the button.
<Button Margin="0,10" Name="mainButton" Click="mainButton_Click">
<Button.Content>
<Image Source="C:/reference-to-image" Height="30"/>
</Button.Content>
</Button>
In the background you can than change the Picture.
This question shows how to do that in the background.
WPF Image UriSource and Data Binding using http:\\ URL
PS. If you want to change the behavior of controls on certain events things like pressing the left mouse button on it, you have to overwrite the event triggers using
<Style TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
...
Hope this helps.
UPDATE
You can set the BorderThickness to 0 and than set the Value of the Padding Property to 0. The Button Control has a predefined padding value, which makes it look like it has a border.
Padding is the space inside the control and the content e.g the space between the button and the picture
<StackPanel Orientation="Horizontal">
<Button Click="Button_Click" Padding="0" BorderThickness="0">
<Image Source="link-to-pic" Height="100"/>
</Button>
<Button Click="Button_Click" Padding="0" BorderThickness="0">
<Image Source="link-to-pic" Height="100"/>
</Button>
</StackPanel>

WPF Ribbon Button enable status doesn't sync with corresponding QAT button

I define a Ribbon with a Ribbon Button.
<Ribbon x:Name="ribbonMenu" Background="White" Loaded="ribbonMenu_Loaded">
<RibbonTab Header="{StaticResource File}">
<RibbonGroup Header="{StaticResource File}">
<c1:C1DockPanel>
<RibbonButton Name="mMasterMaintaince" Label="{StaticResource mMasterMaintaince}" QuickAccessToolBarId="mWebpack"
LargeImageSource="/WpfDemo;component/Resources/Images/icon.ico"
SmallImageSource="/WpfDemo;component/Resources/Images/icon.ico"
RibbonTwoLineText.HasTwoLines="True"
</c1:C1DockPanel>
</RibbonGroup>
</RibbonTab>
</Ribbon>
<Button x:Name="enable" Content="Enable" HorizontalAlignment="Left" Margin="159,165,0,0" VerticalAlignment="Top" Width="90" Height="29" Click="button_Click"/>
Basically when user click enable button it will toggle the enable status of the mMasterMaintaince ribbon button (through IsEnable property of the ribbon button).
Everything works fine until I try to add the mMasterMaintaince to the Quick Access Toolbar.
When user press the enable button, only the mMasterMaintaince ribbon button's enable status is toggled, the corresponding Quick Access Toolbar button doesn't change the state.
I thought they are the same button.
I know that in the event handler of enable button I could loop through ribbonMenu.QuickAccessToolBar.Items to find the corresponding button and change its enable state but I wonder if there is more elegant way to do it.

TabItem Header looks different as a Label

I have a TabItem and was previously setting the Header within the object like so,
<TabItem x:Name="Checked_Out_Items" Header="Clients In Use" Height="40" LostFocus="Checked_Out_Items_LostFocus" GotFocus="Checked_Out_Items_GotFocus" BorderThickness="0" >
However, I've run into the problem where there is not a Click event for this Tab. I found a solution where we can insert a label as the header specified here,
how to handle TabItem single click event in WPF?
But, the Label looks nothing like what I need. Here is the Tab Header defined inside the object.
Here's what it looks like with the label
<TabItem x:Name="Checked_Out_Items" Height="40" LostFocus="Checked_Out_Items_LostFocus" GotFocus="Checked_Out_Items_GotFocus" BorderThickness="0" >
<TabItem.Header>
<Label Content="Clients In Use" Height="40" MouseLeftButtonDown="Checked_Out_Items_Clicked" Width="171" />
</TabItem.Header>
Lets separate the concerns a bit.
In order to handle a mouse click event, a control needs to be prepared for receiving this event, it needs to implement a handler and the handler must actually receive the event. In case of TabItem the mouse click event is consumed by the control, without releasing the event to user defined listeners.
On the level of TabItem, the best option would be to handle the PreviewMouseLeftButtonDown event, but this is not an option if event handling shouldn't occur when child controls have their own handling functionality.
So the other option is to handle the MouseLeftButtonDown event before it reaches the TabItem, which means to handle it in a child control of the tab item.
As said, in order to receive the event, the control needs to be ready to receive the event. This means, it needs a Background not null (can be Transparent) and IsHitTestEnabled="True" (which is default in most cases) and it must actually handle the event.
For the showcase, I use a Red instead of Transparent background color. The red area is the place where mouse clicks are captured and handled.
<TabItem Padding="0">
<TabItem.Header>
<Border Height="30" Width="50"
Background="Red" MouseLeftButtonDown="Item_MouseLeftButtonDown">
<ContentPresenter
VerticalAlignment="Center" HorizontalAlignment="Center"
Content="T2"/>
</Border>
</TabItem.Header>
Test Content 2
</TabItem>
Or, in order to have a better separation between header content and click handling, a HeaderTemplate can be used:
<TabItem Header="T3" Padding="0">
<TabItem.HeaderTemplate>
<DataTemplate>
<Border MinHeight="30" MinWidth="50"
Background="Red" MouseLeftButtonDown="Item_MouseLeftButtonDown">
<ContentPresenter
VerticalAlignment="Center" HorizontalAlignment="Center"
Content="{Binding}"/>
</Border>
</DataTemplate>
</TabItem.HeaderTemplate>
Test Content 3
</TabItem>
The issue with any approach that relies on child controls is, that there is still a border of the TabItem and if the user clicks that border, the click will be outside of the child control and the tab will be selected without executing the click handler.
So a different way to handle tab changes (not clicks!) would be to handle the TabControl.SelectionChanged event and filter for events that actually originate from the TabControl and not from some inner content elements.
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source == sender)
{
// this selection change is actually issued because of a tab change
}
}
Another thing I just realized: The same condition could be used in TabItem.PreviewMouseLeftButtonDown in order to filter clicks to the tabitem header vs click events originating from the content area.
Edit:
The reason why Label is looking different is, that a font style is active for TabItem and Label is using some of its internal styles, ignoring the TabItem style.

WPF: Mystery with RichTextBox and KeyDown Event

Before I explain, I will present code, because it is the best way to express the question in this case. a simple WPF window, his base node contains this:
<StackPanel>
<Menu>
<TextBox x:Name"A" Width="200" />
</Menu>
<TextBlock Margin="0,10,0,0">--richTB--</TextBlock>
<RichTextBox x:Name"B" />
<TextBlock Margin="0,10,0,0">--simpleTB--</TextBlock>
<TextBox x:Name"C" />
</StackPanel>
Now, if the focus is in the buttom TextBox (C), and by a Mouse-click I move focus to the top TextBox within menu (A), and then I hit Enter key, the focus returns to the buttom TextBox (C). This behavior of the MenuItem that Enter key "selects" and returns the focus. so far everything is normal.
But, if i focus RichTextBox (B), and then I go through the top TextBox (A), when I tap Return cursor will remain in the box.
I made another little test, and I listening the PreviewKeyDown & KeyDown events for the TextBox within menu (A). So:
<Menu>
<TextBox Width="200" KeyDown="TB_KeyDown" PreviewKeyDown="TB_PreviewKeyDown" />
</Menu>
What I discovered? The last scenario in which the focus was first RichTextBox (B) and then in TextBox within menu (A), there are no listening to the KeyDown for Enter key!

WPF ToolTip animation and template

I am trying to set up a ToolTip similar than Microsoft uses in Outlook 2013:
How can I incorporate the following behaviour:
ToolTip stays open as long as the mouse cursor is inside it
(my version: ToolTip closes automatically after certain time has elapsed)
Allow clicking components inside ToolTip (for example "See more online" above is clickable)
(my version: ToolTip is already closed when trying to move mouse cursor inside it)
ToolTip "scrolls" from top to down when it opens
(my version: ToolTip opens without animation)
XAML:
<TextBlock Text="ToolTip example" ToolTipService.ShowDuration="12000">
<TextBlock.ToolTip>
<ToolTip Padding="5">
<Grid>
</Grid>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>

Resources