How to change DynamicResource in WPF - wpf

I have a UserControl with that XAML:
<StackPanel>
<Label HorizontalContentAlignment="Center">
<Rectangle Name="iconContainer" Height="120" Width="120" Fill="#FF045189">
<Rectangle.OpacityMask>
<VisualBrush Visual="{DynamicResource appbar_disconnect}"/>
</Rectangle.OpacityMask>
</Rectangle>
</Label>
<TextBlock Name="tBlockPortStatus" Foreground="#FF7C7676" FontWeight="Bold" FontSize="15" Margin="3" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap">PORT STATUS (Testing wrapping text abilities for this control)</TextBlock>
</StackPanel>
I need to change the icon(named appbar_disconnect) and use another DynamicResource (ex. appbar_connect) using Code Behind or MVVM.
How can I achieve this?
Regards

Your case looks like it would be better handled using a Trigger than a DynamicResource, but if you insisted on using DynamicResource, you basically need to define your states' icons/images as resources in the App.xaml file:
<Application.Resources>
<Image Source="Icons/disconnect.png" x:Key="AppbarDisconnect"/>
<Image Source="Icons/connect.png" x:Key="AppbarConnect"/>
<Image Source="Icons/undefined.png" x:Key="AppbarStatus"/>
</Application.Resources>
Assuming your UserControl looks like that:
<StackPanel>
<Label HorizontalContentAlignment="Center">
<Rectangle Name="IconContainer" Height="120" Width="120" Fill="#FF045189">
<Rectangle.OpacityMask>
<VisualBrush Visual="{DynamicResource AppbarStatus}"/>
</Rectangle.OpacityMask>
</Rectangle>
</Label>
<TextBlock Name="TBlockPortStatus" Foreground="#FF7C7676" FontWeight="Bold" FontSize="15" Margin="3" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap">PORT STATUS (Testing wrapping text abilities for this control)</TextBlock>
</StackPanel>
You could update the AppbarStatus resource on a specific event (from the code behind or from the viewmodel) like so:
Application.Current.Resources["AppbarStatus"] = Application.Current.Resources["AppbarDisconnect"];
Update
In case you want to use a DataTrigger, just add a property to hold the connection-status to your user control:
private bool _connetionStatus;
public bool ConnectionStatus
{
get { return _connetionStatus; }
set
{
if (value == _connetionStatus) return;
_connetionStatus = value;
OnPropertyChanged();
}
}
The DataTrigger should be self explanatory:
<StackPanel>
<Label HorizontalContentAlignment="Center">
<Rectangle Name="IconContainer" Height="120" Width="120" Fill="#FF045189">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="OpacityMask">
<Setter.Value>
<VisualBrush Visual="{DynamicResource AppbarDisconnect}"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ConnectionStatus}" Value="true">
<Setter Property="OpacityMask">
<Setter.Value>
<VisualBrush Visual="{DynamicResource AppbarConnect}"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Label>
<TextBlock Name="TBlockPortStatus" Foreground="#FF7C7676" FontWeight="Bold" FontSize="15" Margin="3" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap">PORT STATUS (Testing wrapping text abilities for this control)</TextBlock>
</StackPanel>

Related

Button within ListBox ItemTemplate not selecting item wpf mvvm

Hi i have the same problem as here Button within ListBox ItemTemplate not selecting item
And i know the reason why my button doesnt see selected item, it because listbox is called when MouseDown
and button is called on Click. But i dont know how to fix it
XAML
<ListBox Grid.Row="1" x:Name="ListViewProduct" Background="#FFf1f1f1" ItemsSource="{Binding Videos}" >
<ListBox.ItemTemplate>
<!-- FIX Ripple-->
<DataTemplate >
<Border Background="White" Name="border" Margin="50 10 50 10" Width="310" Height="360">
<StackPanel>
<Border Width="300" Height="300" CornerRadius="5" Margin="5">
<Border.Effect>
<DropShadowEffect ShadowDepth="5"/>
</Border.Effect>
<Border.Background>
<ImageBrush ImageSource="{Binding Image}"/>
</Border.Background>
</Border>
<Grid>
<StackPanel>
<TextBlock Margin="5" Text="{Binding Name}" FontSize="14" FontFamily="Franklin Gothic Medium" />
<TextBlock Margin="5 0" Text="{Binding User.Name}" FontSize="13" />
</StackPanel>
<Button HorizontalAlignment="Right" Margin="0 0 10 0"
Command="{Binding ElementName= ListViewProduct,Path=DataContext.DownloadPageCommand}"
CommandParameter="{Binding Path=SelectedItem , ElementName=ListViewProduct}">
<materialDesign:PackIcon Width="25" Height="25" Kind="Download" Foreground="White"/>
</Button>
</Grid>
</StackPanel>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding ElementName= ListViewProduct,Path=DataContext.ViewWatchingPageCommand}"
CommandParameter="{Binding Path=SelectedItem , ElementName=ListViewProduct}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
C#
private RelayCommandParametr _downloadpageCommand;
public RelayCommandParametr DownloadPageCommand
{
get
{
return _downloadpageCommand
?? (_downloadpageCommand = new RelayCommandParametr(
obj =>
{
SelectedVideo = obj as Video;
_navigationService.NavigateTo("Download",obj);
}));
}
}
private RelayCommandParametr _viewWatchingPageCommand;
public RelayCommandParametr ViewWatchingPageCommand
{
get
{
return _viewWatchingPageCommand
?? (_viewWatchingPageCommand = new RelayCommandParametr(
(obj) =>
{
SelectedVideo = obj as Video;
_navigationService.NavigateTo("VideoWatching",SelectedVideo);
}));
}
}
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
I find answer i just set selected item.

Color a WPF ListBox item based on a property

I have an observable collection of Song objects. These song objects have a property called "Playing" that is a bool (bad naming, I know). The songs display in a ListBox in my application. I want the song that is Playing to be colored red. I have been working with triggers all day trying to make this work. So far, I have gotten to the point where they are colored based on what Playing is set to when the song is added to the list. Is it possible to make it change when the Playing property changes?
Here is my XAML:
<Window x:Class="MusicPlayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MusicPlayer="clr-namespace:MusicPlayer" Title="Music" Height="350" Width="525" Name="Main">
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<Button Content="Play" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayButton_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Center" Margin="0,0,165,20" Name="stopButton" VerticalAlignment="Bottom" Width="75" Click="stopButton_Click" />
<Button Content="Next" Height="23" HorizontalAlignment="Center" Margin="165,0,0,20" Name="nextButton" VerticalAlignment="Bottom" Width="75" Click="nextButton_Click" />
<Button Content="Add Songs..." Height="23" HorizontalAlignment="Center" Margin="330,0,0,20" Name="AddButton" VerticalAlignment="Bottom" Width="75" Click="AddButton_Click" />
<Button Content="Previous" Height="23" HorizontalAlignment="Center" Margin="0,0,0,20" Name="PreviousButton" VerticalAlignment="Bottom" Width="75" Click="PreviousButton_Click" />
<Button Content="Pause" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Visibility="Hidden" Click="PauseButton_Click" />
<Menu Height="23" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Quit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<Slider Height="23" HorizontalAlignment="Stretch" Margin="10,0,10,50" Name="ProgressBar" VerticalAlignment="Bottom" />
</Grid>
</Window>
Edit:
After implementign INotifyPropertyChanged, The color will change to red using either the above or below XAML. Now, it won't change back white using either method. I am also having a problem where my Play method will not change the background color to red, but my next method will. Here is my code: http://pastebin.com/EMTUpTin http://pastebin.com/LuK78zGp
Here is my new XAML:
<Window x:Class="MusicPlayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MusicPlayer="clr-namespace:MusicPlayer" Title="Music" Height="350" Width="525" Name="Main">
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}">
<TextBlock.Background>
<SolidColorBrush Color="{Binding BackgroundColor}"/>
</TextBlock.Background>
</TextBlock>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<Button Content="Play" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayButton_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Center" Margin="0,0,165,20" Name="stopButton" VerticalAlignment="Bottom" Width="75" Click="stopButton_Click" />
<Button Content="Next" Height="23" HorizontalAlignment="Center" Margin="165,0,0,20" Name="nextButton" VerticalAlignment="Bottom" Width="75" Click="nextButton_Click" />
<Button Content="Add Songs..." Height="23" HorizontalAlignment="Center" Margin="330,0,0,20" Name="AddButton" VerticalAlignment="Bottom" Width="75" Click="AddButton_Click" />
<Button Content="Previous" Height="23" HorizontalAlignment="Center" Margin="0,0,0,20" Name="PreviousButton" VerticalAlignment="Bottom" Width="75" Click="PreviousButton_Click" />
<Button Content="Pause" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Visibility="Hidden" Click="PauseButton_Click" />
<Menu Height="23" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Quit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<Slider Height="23" HorizontalAlignment="Stretch" Margin="10,0,10,50" Name="ProgressBar" VerticalAlignment="Bottom" />
</Grid>
</Window>
Edit 2:
I just noticed I am having another problem. If I highlight one of the items with a white background, the text is invisible. How do I fix this?
Edit 3:
Fixed this problem by setting the background to Colors.Transparent instead of Colors.White.
In order to have it change back, wouldn't you also have to implement a trigger for when Playing is False? Like so:
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Playing}" Value="False">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>
This seems like the simplest solution to me. Of course you can change Value="White" to whatever color you need.
Does your object with the Playing property implement INotifyPropertyChanged ? If it does, then your UI should auto-update based on the DataTrigger approach you are using.
Another approach is to use ViewModels instead of Triggers (easier to understand and work with - when things don't go as expected) An example
Update:
Just looked at your code snippets. One thing I found - you need to trigger the event after you've applied the new value.
public Color BackgroundColor
{
get { return _backgroundColor; }
set
{
_backgroundColor = value;
NotifyPropertyChanged("BackgroundColor"); // must be after so that new value is readable by the GUI
}
}
Also the dataTemplate must be applied to the ItemTemplate property of the listbox
<ListBox.ItemTemplate> <!-- not Resources property -->
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
I basically changed the snippet from the example that I posted to use your song class and then modified the button click to toggle between 2 colors. (Also turned ListView into ListBox)
private bool _isGreen = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (var item in Items)
item.BackgroundColor = (_isGreen ? Colors.Cyan : Colors.PaleGreen );
_isGreen = !_isGreen;
}
My listboxes change color on every click! :)

Can we have buttons in a validation template, and how can we bind it to the ViewModel method?

Requirement:
Need to display an error message when the user types a forlder name that doesn't exist as shown below:
Problem: I am able to display the UI but not able to call a method in the view model when the user clicks on the button "CreateNew"
View Model Code:
public string this[string columnName]
{
get { return "The entered folder name doesn't exist."; }
}
RelayCommand createNewFolder;
public RelayCommand CreateNewFolder
{
get
{
if (createNewFolder == null)
createNewFolder = new RelayCommand(param => this.OnCreateNewFolder());
return createNewFolder;
}
}
public void OnCreateNewFolder()
{
MessageBox.Show("CreateNewFolder");
}
RelayCommand.cs can be downloaded at: http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=mag200902MVVM&DownloadId=4357
Xaml Code:
<Window.Resources>
<ControlTemplate x:Key="validationTemplate">
<DockPanel LastChildFill="True">
<Border Margin="5,5,0,0" DockPanel.Dock="Bottom" Background="Red">
<StackPanel>
<TextBlock Name="ErrorText" Foreground="White" Background="Red"
FontSize="12" Padding="2" FontFamily="Trebuchet MS"
TextWrapping="Wrap"
Text="{Binding [0].ErrorContent}" ></TextBlock>
<StackPanel Margin="0" Orientation="Horizontal">
<Button Content="Create New" Command="{Binding Path=CreateNewFolder}" Margin="10" Padding="5"></Button>
<Button Content="Cancel" Margin="10" Padding="5" ></Button>
</StackPanel>
</StackPanel>
</Border>
<AdornedElementPlaceholder Name="ErrorTextBox" />
</DockPanel>
</ControlTemplate>
<Style x:Key="ValidationStyle" TargetType="{x:Type ComboBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BitmapEffect">
<Setter.Value>
<BitmapEffectGroup>
<OuterGlowBitmapEffect GlowColor="Red" GlowSize="3" Noise="0.6"></OuterGlowBitmapEffect>
</BitmapEffectGroup>
</Setter.Value>
</Setter>
<Setter Property="DataContext"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=DataContext}">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<AdornerDecorator >
<ComboBox IsEditable="True" FontSize="11" Margin="10" Width="250"
VerticalAlignment="Center"
Text="{Binding Path=StrText, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
Validation.ErrorTemplate="{StaticResource validationTemplate}"
Style="{StaticResource ValidationStyle}"></ComboBox>
</AdornerDecorator>
</Grid>
Please note that i set the DataContext property in the style:
<Setter Property="DataContext" Value="{Binding RelativeSource={x:Static
RelativeSource.Self},Path=DataContext}">
</Setter>
Please let me know how to bind the method to a button in the validation template.
You could reference the DataContext for the AdornerDecorators Child in the Binding. I think something like this will work
<Button Content="Create New"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type AdornerDecorator}},
Path=Child.DataContext.CreateNewFolder}"
Margin="10" Padding="5"></Button>
This line looks suspicious:
createNewFolder = new RelayCommand(param => this.OnCreateNewFolder());
Maybe you should replace it by:
createNewFolder = new RelayCommand(OnCreateNewFolder);

Customize a TextBlock in WPF

I need to "decorate" a textBlock with a custom background (say, when IsSelected)
Actually I have two separate elements textBlock and its background rectangle:
<TextBlock x:Name="StopText" Text="Eiffel Tower"
Canvas.Left="17"
FontSize="14"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
FontFamily="Giddyup Std"
Canvas.Top="-16"
Padding="5">
</TextBlock>
<Rectangle x:Name="ShadowRectangle"
Fill="SkyBlue"
Canvas.Left="18"
Width="{Binding ElementName=StopText, Path=ActualWidth}"
Height="{Binding ElementName=StopText, Path=ActualHeight}"
RadiusX="5" RadiusY="5" Opacity="0.2" Canvas.Top="-17"
LayoutTransform="{Binding ElementName=StopText, Path=LayoutTransform}"/>
Now, when I want to Hide the textBlock I need to hide the rectangle too, etc. I think there is should be a more elegant way to do it.
Any remarks appreciated.
EDIT
Border approach
<Border x:Name="ShadowRectangle"
Background="Transparent"
Canvas.Left="18"
Canvas.Top="-17"
CornerRadius="5"
Opacity="0.2"
LayoutTransform="{Binding ElementName=StopText,
Path=LayoutTransform}">
<TextBlock x:Name="StopText" Text="Eiffel Tower"
FontSize="14" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" FontFamily="Giddyup Std"
Canvas.Top="-16" Padding="5">
</TextBlock>
</Border>
In a solution similar to your border approach, if you want no dependencies between the opacity of the border and the textblock, you could go with something like this:
<grid>
<rectangle />
<textblock />
<grid>
this should put the textblock over the rectangle since they are on the same grid cell.
They you only have to change the Rectangle.Fill when it's selected. You could do that using a DataTrigger on the Rectangle style.
You can make a Custom Control instead.
Here is a link for some ideers:
http://www.codeguru.com/cpp/i-n/internet/xml/article.php/c12521
Bind the visibility property for both the textblock and Rectangle to a bool in your viewmodel and use the BoolToVisibilityConverter to convert the bool value to a visibility value. Your XAML will look something like this:
<TextBlock x:Name="StopText" Text="Eiffel Tower"
Canvas.Left="17"
FontSize="14"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
FontFamily="Giddyup Std"
Canvas.Top="-16"
Padding="5"
Visibility="{Binding IsVis, Converter={StaticResource BooleanToVisibilityConverter}}">
</TextBlock>
<Rectangle x:Name="ShadowRectangle"
Fill="SkyBlue"
Canvas.Left="18"
Width="{Binding ElementName=StopText, Path=ActualWidth}"
Height="{Binding ElementName=StopText, Path=ActualHeight}"
RadiusX="5" RadiusY="5" Opacity="0.2" Canvas.Top="-17"
Visibility="{Binding IsVis, Converter={StaticResource BooleanToVisibilityConverter}}"/>
Using either the Border or Rectangle approach, you should be able to bind the Visibility of the decorator (Border or Rectangle) to the Visibility of the TextBlock.
<TextBlock x:Name="StopText" Text="Eiffel Tower"
Canvas.Left="17"
FontSize="14"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
FontFamily="Giddyup Std"
Canvas.Top="-16"
Padding="5">
</TextBlock>
<Rectangle x:Name="ShadowRectangle"
Fill="Red"
Canvas.Left="18"
Width="{Binding ElementName=StopText, Path=ActualWidth}"
Height="{Binding ElementName=StopText, Path=ActualHeight}"
RadiusX="5" RadiusY="5" Opacity="0.2" Canvas.Top="-17"
LayoutTransform="{Binding ElementName=StopText, Path=LayoutTransform}"
Visibility="{Binding ElementName=StopText}"/>
Let me suggest to use templated label (textblock wont accept templates and took more characters to type -). For your convenience, I wrapped it in a style:
<Window x:Class="_4203457.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Giddyup Std"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Grid>
<TextBlock Text="{TemplateBinding Content}"
FontSize="14"
Padding="5"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
FontFamily="Giddyup Std"
/>
<Rectangle x:Name="ShadowRectangle"
Fill="SkyBlue"
RadiusX="5" RadiusY="5" Opacity="0.5"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Height="27" Width="454">
<Label Content="Eiffel Tower"/>
</Grid>

WPF Buttons Style

I have WPF Form which has many buttons with the same code. Appearance of all buttons must be the same
For example, code for one of these buttons
<Button x:Name="btnAddRelative" Width="120" Click="btnAddRelative_Click" >
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock Text=" Add Relative" Height="20" VerticalAlignment="Center"/>
</StackPanel>
</Button.Content>
</Button>
How can I create one style and use it for all my buttons. All buttons has the same png image, only their text different. How can I do this.
I tried to do this with Style object in Resource Section:
<UserControl.Resources>
<Style TargetType="Button" x:Key="AddStyle">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock Text=" " Height="20" VerticalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
But this code not work. Can any body know how can I do this?
If the image is fix you can hard-code it in the style, and use the Content property of Button bin to the Content of TextBox
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel
Orientation="Horizontal">
<!--<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>-->
<TextBlock
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Content}"
Height="20"
VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
just try this
<Window.Resources>
<Style TargetType="Button"
x:Key="AddStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal">
<Image Height="26"
Width="20"
HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="/WpfApplication33;component/Images/MoveLeft.png" />
</Image.Source>
</Image>
<TextBlock Text ="{TemplateBinding Content}"
Height="20"
/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource AddStyle}"
Height="25" Width="100"
Content="Button1"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button22"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button2233"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button2332"></Button>
</StackPanel>
</Grid>
Note: Use ContentPresenter instead of TextBlock if you have to display anything other than flat text
Try changing your style as follows
<UserControl.Resources>
<Style
TargetType="Button"
x:Key="AddStyle">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel
Orientation="Horizontal">
<Image
Height="26"
HorizontalAlignment="Left">
<Image.Source>
<BitmapImage
UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock
Text=" "
Height="20"
VerticalAlignment="Center" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
[Edit inspired by comment]
You could create a new UserControl, lets call it AddButtonContent containing your Stackpanel and such, then include that within your button, like so:
<Button>
<local:AddButtonContent
ButtonText="Testing, one, two, three" />
</Button>
You'll need to add a xmlns reference called local (or whatever you'd like to call it) to the UserControl with all of the buttons.
The codebehind portion of your AddButtonContent UserControl will need the following code, and you'll need to name your TextBlock (I used testText for this example).
public static DependencyProperty ButtonTextProperty =
DependencyProperty.Register("ButtonText",
typeof(string),
typeof(AddButtonContent),
new PropertyMetadata("", onTextChangedCallback));
public string ButtonText
{
get { return (string)GetValue(ButtonTextProperty); }
set
{
SetValue(ButtonTextProperty, value);
}
}
static void onTextChangedCallback(
DependencyObject dobj,
DependencyPropertyChangedEventArgs args)
{
AddButtonContent abc = dobj as AddButtonContent;
abc.testText.Text = args.NewValue.ToString();
}

Resources