|
|
Thank You , I just ordered the book.
Frazzle the name say's it all
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
John F. Woods
|
|
|
|
|
I'd second this book - in fact, have a look at the inside cover and you'll see recommendations from people like Josh, Sacha and me.
|
|
|
|
|
Couldn't find you in my copy; is there a hardback version?
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
We're in the one for WPF 4.0.
|
|
|
|
|
|
Thank you, I am checking it out now.
Frazzle the name say's it all
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
John F. Woods
|
|
|
|
|
i'm indebted with this other book:
Pro WPF in .NET 4 - by Matthew MacDonald (Apress)[^]
the source code for this book is also available there.
what you will get?:
.every major WPF feature
.useful source code examples (accessible enough to understand quickly)
|
|
|
|
|
I can only read one at a time. but Thank You. It's hard to pass up on the heavy endorsements from all the article writers here on code project.
If I still need help after reading it I will buy that one also.
Frazzle the name say's it all
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
John F. Woods
|
|
|
|
|
Ok, so I have my tab style working. The tabs now show the text and a close button. Here's my style:
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate >
<Grid HorizontalAlignment="Stretch" Height="22">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2" ></RowDefinition>
<RowDefinition Height="Auto" ></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="1" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem} }, Path=Header}"
VerticalAlignment="Bottom" Margin="4,0,8,0"/>
<Button Grid.Row="1"
Grid.Column="1"
Height="16"
Width="16"
BorderBrush="{x:Null}" Background="{x:Null}"
Foreground="#FF224A71"
VerticalAlignment="Center"
Padding="3,0"
Command="{Binding CloseTabCommand}">
<TextBlock Text="x"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="0,0,0,2"/>
<Button.ToolTip>
<controls:ToolTipEx Style="{StaticResource TooltipStyle}"
HeaderText="Close"
Icon="/FMG.UI.WPF;component/Media/Images/home_16.png"
ContentAreaText="Closes this tab"/>
</Button.ToolTip>
<Button.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#4BFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Button.OpacityMask>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<!--<Controls:CloseTabbedViewAction />-->
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
You can see the button is bound to a CloseTabCommand.
When I run it, the command isn't fired. Here's the command from the VM:
private ICommand _CloseTabCommand;
public ICommand CloseTabCommand
{
get
{
if (_CloseTabCommand == null)
_CloseTabCommand = new RelayCommand(p => closeTabExecuted(), p => closeTabCanExecute());
return _CloseTabCommand;
}
}
What am I doing wrong?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
As this is inside a template, you aren't getting the DataContext . The easiest way to solve this is to use FindAncestor to find the TabItem that this belongs to and get the DataContext from that.
|
|
|
|
|
Ok, I see. I'm trying this but it's still not firing:
<Button Grid.Row="1"
Grid.Column="1"
Height="16"
Width="16"
BorderBrush="{x:Null}" Background="{x:Null}"
Foreground="#FF224A71"
VerticalAlignment="Center"
Padding="3,0"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=CloseTabCommand}"
>
If it's not broken, fix it until it is
|
|
|
|
|
You need to be looking for the TabItem, not the Button as an ancestor.
|
|
|
|
|
Ok, so now I have this:
<Button Grid.Row="1"
Grid.Column="1"
Height="16"
Width="16"
BorderBrush="{x:Null}"
Background="{x:Null}"
Foreground="#FF224A71"
VerticalAlignment="Center"
Padding="3,0"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=CloseTabCommand}">
It's still not workong. I have a context menu on the tab which includes Close and the command works from there, but not from this button.
If it's not broken, fix it until it is
|
|
|
|
|
The AncestorType should be the bound to the control that is in turn bound to the VM. In most cases this is the Window/UserControl and not really the particular control in that Window, if you get what I mean.
Say you have a Window with it's DataContext set to the ViewModel that contains the CloseTabCommand, then you would do this
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=CloseTabCommand}" .
Hope this helps
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
It still doesn't know about the DataContext though. To fix this, replace it with this:
<Button Grid.Row="1"
Grid.Column="1"
Height="16"
Width="16"
BorderBrush="{x:Null}" Background="{x:Null}"
Foreground="#FF224A71"
VerticalAlignment="Center"
Padding="3,0"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=DataContext.CloseTabCommand}">
|
|
|
|
|
Thanks Pete. That did it!! +5
If it's not broken, fix it until it is
|
|
|
|
|
|
Yes I am. Learning is a team sport.
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
I'm trying to style a tab item like this[^].
So I copied this style into my view, but I don't understand how to apply this. Where/how in the TabControl XAML do I use this?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
Put it into a Resources section and drop the x:Key part to have it automatically applied to the TabItem elements.
|
|
|
|
|
Ok, so that sorta worked. I get the button, but not the header text
If it's not broken, fix it until it is
|
|
|
|
|
[UPDATE] Found it..
I have a listbox with hyperlinks as the list items. But the selected item is a blue bar with white text. I'd like to remove the highlighting. Here's what I have so far:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<Trigger Property="IsMouseCaptureWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type models:JobModel}">
<StackPanel Orientation="Horizontal"
Margin="2">
<Image Source="/FMG.UI.WPF;component/Media/Images/job_72.png"
Height="16"
Width="16"
Margin="0,0,3,0"/>
<controls:TextBlockEx>
<Hyperlink Style="{StaticResource linkStyle}"
Command="{Binding SelectedJob, Mode=TwoWay}">
<TextBlock Text="{Binding JobNumber}"/>
</Hyperlink>
</controls:TextBlockEx>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
and
<ListBox Grid.Row="1"
Grid.Column="0"
ItemsSource="{Binding Jobs}"
SelectedItem="{Binding SelectedJob}"
BorderThickness="1"
BorderBrush="#6593CF"
Margin="-1,0,-1,-1">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
</ListBox>
Can someone show me how to remove the selected item's fore & back color so it ddoesn't appear selected?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
<pre lang="text">
1.How to bind the MenuItem Command of ListBoxItem ContextMenu dynamically?
2. How to set its CommandParameter?
//----------------------------------
//MainWindowView.xaml
//----------------------------------
<Window x:Class="MVVM.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:vm="clr-namespace:MVVM.ViewModels"
Title="MainView" Height="354" Width="520">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<!--In this ListBox, the MenuItem command can not be called-->
<ListBox Height="252" HorizontalAlignment="Left" Margin="12,51,0,0" Name="listBox1" VerticalAlignment="Top" Width="201"
ItemsSource="{Binding Path=TestItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Width="150">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Call Command1" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Command1}" CommandParameter="???"/><!--here the Command1 not be called-->
</i:EventTrigger> <!--how to set command parameter to this ListBoxItem displaying text?-->
</i:Interaction.Triggers>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--In this ListBox, the menuitem command can be called,
but the command parameter can not be set correctly-->
<ListBox Height="252" HorizontalAlignment="Left" Margin="230,51,0,0" Name="listBox2" VerticalAlignment="Top" Width="229"
SelectedItem="{Binding SelectedText,Mode=OneWayToSource}">
<ListBoxItem>
<TextBlock Text="item1" Name="tb" />
<ListBoxItem.ContextMenu>
<ContextMenu>
<MenuItem Header="Call Comand1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<!--this one can be called correctly,
but the command parameter can not be set correctly-->
<i:InvokeCommandAction Command="{Binding Command1}" CommandParameter="{Binding ElementName=tb,Path=Text}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
</ContextMenu>
</ListBoxItem.ContextMenu>
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="item2"/>
<ListBoxItem.ContextMenu>
<ContextMenu>
<MenuItem Header="Call Comand1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Command1}" CommandParameter="" />
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
</ContextMenu>
</ListBoxItem.ContextMenu>
</ListBoxItem>
</ListBox>
<Label Content="This one can not work" Height="28" HorizontalAlignment="Left" Margin="12,25,0,0" Name="label1" VerticalAlignment="Top" />
<Label Content="This one can work" Height="28" HorizontalAlignment="Left" Margin="230,25,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="Test ListBox ContextMenu" Height="28" HorizontalAlignment="Left" Margin="12,0,0,0" Name="label3" VerticalAlignment="Top" />
</Grid>
</Window>
//------------------
//MainWindowViewModel.cs
//---------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
using MVVM.Command;
namespace MVVM.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public List<string> TestItems
{
get
{
return new List<string>()
{
"Item1",
"Item2",
"Item3"
};
}
}
public ListBoxItem SelectedText
{
get;
set;
}
public MainWindowViewModel()
{
}
private ICommand _command1;
public ICommand Command1
{
get
{
if(null==_command1)
{
_command1 = new DelegateCommand<string>((str) =>
{
MessageBox.Show("Command1 with parameter:" + str+((TextBlock)SelectedText.Content).Text);
});
}
return _command1;
}
}
ICommand _command2;
public ICommand Command2
{
get
{
if (null == _command2)
{
_command2 = new DelegateCommand<Button>((button) =>
{
if (null == button)
return;
Point p = Mouse.GetPosition(button);
button.Content = string.Format("{0},{1}", p.X, p.Y);
});
}
return _command2;
}
}
}
}
</pre>
|
|
|
|
|
You have to either bind it to a property in your list item object, or to a static property or hard code it. In your case, you can also just specify "{Binding}" in the command parameter and it will pass in the actual object.
|
|
|
|