I am developing windows phone 8.1 app and I need circular progressbar.
I have this usercontrol code:
<UserControl.Resources>
<Style TargetType="ProgressBar" x:Key="CircularProgressBarStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Grid x:Name="LayoutRoot">
<local:CircularProgressBarViewModel.Attach>
<local:CircularProgressBarViewModel HoleSizeFactor="0.75"/>
</local:CircularProgressBarViewModel.Attach>
<Ellipse Width="{Binding Diameter}" Height="{Binding Diameter}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Stroke="LightGray" Opacity="0.5" Fill="Transparent"
StrokeThickness="10">
</Ellipse>
<local:PiePiece CentreX="{Binding CentreX}" CentreY="{Binding CentreY}"
RotationAngle="0" WedgeAngle="{Binding Angle}"
Radius="{Binding Radius}" InnerRadius="{Binding InnerRadius}"
Fill="Black" Opacity="0.7"/>
<Grid util:GridUtils.RowDefinitions="*,2*,*"
util:GridUtils.ColumnDefinitions="*,2*,*">
<Viewbox Grid.Row="1" Grid.Column="1">
<TextBlock Name="myValue" Text="{myValue value}"
Foreground="WhiteSmoke"
FontWeight="Bold"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Viewbox>
</Grid></Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
How can I change value with the name "myValue" from code behind (for example, from MainPage.xaml.cs) and not from CircularProgressBarViewModel?
If you need to get myValue from your MainPage, where you are using your UserControl you can create DependencyProperty in your control and set any value from page to control.
public sealed partial class YourUserControl: UserControl
{
public static readonly DependencyProperty myValueProperty = DependencyProperty.Register("myValue", typeof(string), typeof(YourUserControl), new PropertyMetadata(string.Empty));
public YourUserControl()
{
this.InitializeComponent();
}
public string myValue
{
get { return (string)GetValue(myValueProperty ); }
set { SetValue(myValueProperty , value); }
}
}
And on the your MainPage like this:
<controls:YourUserControl myValue={Binding YourValue}/>
Related
Unfortunately, I'm unable to understand where there is realization mistake.
The main application window should show a content from view model (HomeView.xaml)
Could you advice, what I has done incorrect?
Thanks in advance.
https://i.stack.imgur.com/mq3PS.png
MainWindow.xaml.cs
using ohb.MVVM.ViewModel;
namespace ohb
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new HomeViewModel();
}
// Moveable window
private void WindowMouseMoving(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
this.DragMove();
}
}
// Exit button
private void CloseButtonClick(object sender, RoutedEventArgs e)
{
Close();
}
}
}
MainWindow.xaml
<Window x:Class="ohb.MainWindow"
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:ohb"
xmlns:viewModel="clr-namespace:ohb.MVVM.ViewModel"
xmlns:view="clr-namespace:ohb.MVVM.View"
mc:Ignorable="d"
Height="600" Width="920"
WindowStyle="None"
ResizeMode="NoResize"
Background="Transparent"
AllowsTransparency="True"
MouseMove="WindowMouseMoving">
<Window.DataContext>
<viewModel:MainViewModel/>
</Window.DataContext>
<Border Background="#2f4f4f"
CornerRadius="30">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Application"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Foreground="White"
FontSize="22"
Margin="20,0,0,0"/>
<StackPanel Grid.Row="1">
<RadioButton Content="Home"
Height="50"
Foreground="White"
FontSize="14"
Style="{StaticResource MenuButtonTheme}"
IsChecked="True"
Command="{Binding HomeViewCommand}"/>
<RadioButton Content="Menu"
Height="50"
Foreground="White"
FontSize="14"
Style="{StaticResource MenuButtonTheme}"
Command="{Binding DiscoveryViewCommand}"/>
<RadioButton Content="Settings"
Height="50"
Foreground="White"
FontSize="14"
Style="{StaticResource MenuButtonTheme}"/>
<RadioButton Content="Exit"
Click="CloseButtonClick"
Height="50"
Foreground="White"
FontSize="14"
Style="{StaticResource MenuButtonTheme}"/>
</StackPanel>
<TextBox Width="250"
Height="40"
VerticalContentAlignment="Center"
HorizontalAlignment="Left"
Margin="5"
Grid.Column="1"
Style="{StaticResource TextBoxTheme}"/>
<ContentControl Grid.Row="1"
Grid.Column="1"
Margin="10"
Content="{Binding CurrentView}"/>
</Grid>
</Border>
</Window>
App.xaml
<Application x:Class="ohb.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ohb"
xmlns:viewModel="clr-namespace:ohb.MVVM.ViewModel"
xmlns:view="clr-namespace:ohb.MVVM.View"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme/MenuButtonTheme.xaml"/>
<ResourceDictionary Source="Theme/TextBoxTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type viewModel:HomeViewModel}">
<view:HomeView/>
</DataTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
MenuButtonTheme.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style BasedOn="{StaticResource {x:Type ToggleButton}}"
TargetType="{x:Type RadioButton}"
x:Key="MenuButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Property=Content}"
VerticalAlignment="Center"
Margin="50,0,0,0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#3b6363"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
TextBoxTheme.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type TextBox}"
x:Key="TextBoxTheme">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border CornerRadius="10"
Background="#3b6363"
Width="200" Height="40">
<Grid>
<Rectangle StrokeThickness="1"/>
<TextBox Margin="1"
BorderThickness="0"
Background="Transparent"
VerticalContentAlignment="Center"
Padding="5"
Foreground="White"
x:Name="SearchBox"/>
<TextBlock IsHitTestVisible="False"
Text="Search"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Foreground="DarkGray"
Grid.Column="1"
FontSize="12">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=SearchBox}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Visibility" Value="Hidden"/>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
ObservableObject.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ohb.Core
{
class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
if (PropertyChanged != null)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
RelayCommand.cs
using System.Windows.Input;
namespace ohb.Core
{
public class RelayCommand : ICommand
{
private Action<object> execute;
private Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
}
}
MainViewModel.cs
using System;
using ohb.Core;
namespace ohb.MVVM.ViewModel
{
class MainViewModel : ObservableObject
{
public RelayCommand HomeViewCommand { get; set; }
public HomeViewModel HomeVM { get; set; }
private object _currentView;
public object CurrentView
{
get { return _currentView; }
set
{
_currentView = value;
OnPropertyChanged();
}
}
public MainViewModel()
{
HomeVM = new HomeViewModel();
CurrentView = HomeVM;
HomeViewCommand = new RelayCommand(o =>
{
CurrentView = HomeVM;
});
}
}
}
HomeViewModel.cs
using ohb.Core;
namespace ohb.MVVM.ViewModel
{
class HomeViewModel
{
}
}
HomeView.xaml
<UserControl x:Class="ohb.MVVM.View.HomeView"
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:viewModel="clr-namespace:ohb.MVVM.ViewModel"
xmlns:view="clr-namespace:ohb.MVVM.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewModel:HomeViewModel/>
</UserControl.DataContext>
<StackPanel>
<TextBlock Text="Discover"
Foreground="White"
FontSize="28"
HorizontalAlignment="Left"
Margin="0,0,0,20"/>
<StackPanel Orientation="Horizontal"
Margin="0,0,0,10">
<Border Width="400"
Height="200">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,2">
<GradientStop Color="#5bc3ff" Offset="0"/>
<GradientStop Color="#3aa0ff" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Border.Clip>
<RectangleGeometry RadiusX="10"
RadiusY="10"
Rect="0,0,400,200"/>
</Border.Clip>
<Grid>
<StackPanel>
<TextBlock Text="World leader
in global"
Foreground="White"
FontSize="28"
Margin="20,10,10,0"/>
<TextBlock Text="Get started"
Foreground="White"
FontSize="18"
Margin="20,10,10,0"/>
</StackPanel>
</Grid>
</Border>
<Border Width="200"
Height="200"
CornerRadius="10"
Margin="45,0,0,0">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,2">
<GradientStop Color="#5bc3ff" Offset="0"/>
<GradientStop Color="#3aa0ff" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</StackPanel>
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="Margin" Value="15,0,0,0"/>
</Style>
</StackPanel.Resources>
<TextBlock Text="most watched"
Foreground="White"
FontSize="20"
HorizontalAlignment="Left"
Margin="0,0,0,10"/>
<StackPanel Orientation="Horizontal">
<Border Width="150"
Height="150"
Background="#844eff"
CornerRadius="10"
Margin="0"/>
<Border Width="150"
Height="150"
Background="Red"
CornerRadius="10"/>
<Border Width="150"
Height="150"
Background="Gray"
CornerRadius="10"/>
<Border Width="150"
Height="150"
Background="Green"
CornerRadius="10"/>
</StackPanel>
</StackPanel>
</StackPanel>
</UserControl>
A UserControl must not explictly set its own DataContext, as you have declared it in HomeView.xaml as
<UserControl.DataContext>
<viewModel:HomeViewModel/>
</UserControl.DataContext>
This assignment breaks the value inheritance of the DataContext property, which is essential to make the below DataTemplate work. Instead of getting the current data item as its DataContext, the control would always use the one that was explicitly set.
<DataTemplate DataType="{x:Type viewModel:HomeViewModel}">
<view:HomeView/>
</DataTemplate>
So simply remove the DataContext assignment from the UserControl's XAML.
I'm trying to develop a HamburgerMenu. a ContentControl that i restyled it.
my xaml code is something like this :
<Style TargetType="local:HamburgerMenu">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:HamburgerMenu">
<Grid x:Name="mainGrid" Background="{TemplateBinding Background}">
<!--HamburgerMenu button-->
<Border x:Name="border" Background="{TemplateBinding Background}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="40" Width="50">
<ToggleButton x:Name="menuIcon" Background="Red" HorizontalAlignment="Left" VerticalAlignment="Top" Height="40" Width="50" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:HamburgerMenu}}, Path=IsOpen}">
<Path x:Name="path" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Uniform" Width="30" Fill="{TemplateBinding MenuIconColor}" Data="M2,15.5L22,15.5 22,17.5 2,17.5 2,15.5z M2,10.5L22,10.5 22,12.5 2,12.5 2,10.5z M2,5.5L22,5.5 22,7.5 2,7.5 2,5.5z"/>
</ToggleButton>
</Border>
<!-- HamburgerMenu Items List-->
<ListBox x:Name="listbox" ItemsSource="{TemplateBinding Content}" HorizontalAlignment="Left" Margin="0,40,0,0" VerticalAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedIndex="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:HamburgerMenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:HamburgerMenuItem">
<Button x:Name="ListBoxItemButton" Command="{TemplateBinding SelectionCommand}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid x:Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.ColumnSpan="2">
<Grid Background="Transparent" Margin="0" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1">
<TextBlock Text="{TemplateBinding Text}" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" FontFamily="Segoe UI Light" FontSize="18" Foreground="{TemplateBinding Foreground}" TextWrapping="Wrap"/>
</Grid>
<Grid Grid.Column="0">
<Image Source="{TemplateBinding Icon}" Margin="10,5,5,5"/>
</Grid>
</Grid>
</Grid>
<Grid Name="ItemSelectedIndicator" Grid.Column="0" Background="{TemplateBinding SelectionIndicatorColor}" Visibility="Collapsed" />
</Grid>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and this is my HamburgerMenu classes :
public class HamburgerMenu : ContentControl
{
public new List<HamburgerMenuItem> Content
{
get { return (List<HamburgerMenuItem>)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public new static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(List<HamburgerMenuItem>), typeof(HamburgerMenu),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
static HamburgerMenu()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HamburgerMenu), new FrameworkPropertyMetadata(typeof(HamburgerMenu)));
}
public override void BeginInit()
{
Content = new List<HamburgerMenuItem>();
base.BeginInit();
}
}
public class HamburgerMenuItem : ListBoxItem
{
static HamburgerMenuItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HamburgerMenuItem), new FrameworkPropertyMetadata(typeof(HamburgerMenuItem)));
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(HamburgerMenuItem), new PropertyMetadata(String.Empty));
}
my question is how i can find witch ListBox item is selected in my window where i used my custom Control.
You could add a "SelectedItem" dependency property to your custom control and bind the SelectedItem property of the ListBox in the ControlTemplate to this one:
<!-- HamburgerMenu Items List-->
<ListBox x:Name="listbox" ItemsSource="{TemplateBinding Content}"
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Left" Margin="0,40,0,0" VerticalAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedIndex="0"/>
You then bind your new dependency property to the source property in your window:
<local:HamburgerMenuItem ... SelectedItem="{Binding YourSourceProperty}" />
I Want to change a DependcyProperty(Named is as MessageTemplateProperty) which is in CustomControl and Type is Controltemplate .
But I can't set the value to it using datatrigger
But another DependcyProperty(named as IsShowMessageProperty) which is in CustomControl and Type is bool can be set using datatrigger.
Who can explain it ,Why, and How to solve it.
The Custom Code as follow:
public class MessageOverLay : ContentControl
{
static MessageOverLay()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageOverLay),
new FrameworkPropertyMetadata(typeof(MessageOverLay)));
}
#region DependcyProperties
// Template attached property
public static readonly DependencyProperty MessageTemplateProperty =
DependencyProperty.Register("MessageTemplate", typeof(ControlTemplate), typeof(MessageOverLay),
new FrameworkPropertyMetadata(MessageTemplateChanged));
public ControlTemplate MessageTemplate
{
set{SetValue(MessageTemplateProperty, value);}
get{return (ControlTemplate)GetValue(MessageTemplateProperty);}
}
// IsVisible attached property
public static readonly DependencyProperty IsShowMessageProperty =
DependencyProperty.Register("IsShowMessage", typeof(bool), typeof(MessageOverLay),
new PropertyMetadata(IsShowMessageChanged));
public bool IsShowMessage
{
get{return (bool)GetValue(IsShowMessageProperty);}
set{SetValue(IsShowMessageProperty, value);}
}
#endregion DependcyProperties
}
The Custom Default Theme Generic.xaml
<Style TargetType="{x:Type controls:MessageOverLay}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:MessageOverLay">
<AdornerDecorator>
<Grid>
<ContentPresenter x:Name="PART_Conent"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Content="{TemplateBinding Content}" />
<Control x:Name="Part_MessageControl" Template="{TemplateBinding MessageTemplate}"
Visibility="{TemplateBinding IsShowMessage,Converter={StaticResource BooleanToVisibilityConverter}}" />
</Grid>
</AdornerDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="MessageTemplate">
<Setter.Value>
<ControlTemplate>
<Grid HorizontalAlignment="Left" VerticalAlignment="Bottom">
<Grid Width="150" Height="100" Margin="5 0 0 10">
<Rectangle Stroke="Black" Fill="Yellow" RadiusX="6" RadiusY="6" Margin="0 20 0 0" />
<TextBlock Text="What are you doing?" Margin="5 25 0 0" />
<Button Content="Cancel" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
<Button Content="OK" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I Want to use it as follow:
Demo XAML:
<Window ...>
<Window.Resources>
<ControlTemplate x:Key="GenderPopupTemplate">
<Grid HorizontalAlignment="Left" VerticalAlignment="Bottom">
<Grid Width="200" Height="100" Margin=" 5 0 0 10">
<TextBlock Text="Please Select Gender " Margin="5 25 0 0" />
<Button Content="Male" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left"
Command="{Binding SelectedGenderCommand}" />
<Button Content="FeMale" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Right"
Command="{Binding SelectedGenderCommand}" />
</Grid>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="FacePopupTemplate">
<Grid HorizontalAlignment="Left" VerticalAlignment="Bottom">
<Grid Width="200" Height="100" Margin="5 10 0 0">
<TextBlock Text="Do you like your Face,Now?" Margin="5 25 0 0" />
<Button Content="OK" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left"
Command="{Binding OKCommand}" />
</Grid>
</Grid>
</ControlTemplate>
</Window.Resources>
<controls:MessageOverLay HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
MessageTemplate="{StaticResource GenderPopupTemplate}"
IsShowMessage="True">
<controls:MessageOverLay.Style>
<Style TargetType="{x:Type controls:MessageOverLay}">
<Style.Triggers>
<DataTrigger Binding="{Binding MessageBoxType}" Value="{x:Static viewModels:MessageBoxTypes.SelectView}">
<Setter Property="MessageTemplate" Value="{StaticResource GenderPopupTemplate}"></Setter>
<Setter Property="Height" Value="350"/>
</DataTrigger>
<DataTrigger Binding="{Binding MessageBoxType}" Value="{x:Static viewModels:MessageBoxTypes.MessageView}">
<Setter Property="MessageTemplate" Value="{StaticResource FacePopupTemplate}"></Setter>
<Setter Property="Height" Value="150"/>
</DataTrigger>
</Style.Triggers>
</Style>
</controls:MessageOverLay.Style>
<Grid Background="SeaGreen"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TextBlock Text="Content"/>
</Grid>
</controls:MessageOverLay>
I want to change the MessageTemplate when the Propery MessageBoxType of MainWindowViewModel changed.
But I can't archive it.
The other related code
Demo C# Code:
public class MainWindowViewModel : BindableBase
{
public ICommand SelectedGenderCommand { get; }
public ICommand OKCommand { get; }
private MessageBoxTypes _messageBoxType;
public MessageBoxTypes MessageBoxType
{
get { return _messageBoxType; }
set { SetProperty(ref _messageBoxType, value); }
}
private string _title = "Prism Unity Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public MainWindowViewModel()
{
MessageBoxType = MessageBoxTypes.SelectView;
SelectedGenderCommand = new DelegateCommand<object>(SelectedGender);
OKCommand = new DelegateCommand<object>(OK);
}
private void OK(object obj)
{
MessageBoxType = MessageBoxTypes.SelectView;
}
private void SelectedGender(object obj)
{
MessageBoxType = MessageBoxTypes.MessageView;
}
}
public enum MessageBoxTypes
{
SelectView,
MessageView,
ConfirmView
}
Update:
Here is the full demo code in github ,Please check it.
When a dependency property is to be set by a Style Setter, there must be no direct assignment of a so-called local value, as you do in
<controls:MessageOverLay MessageTemplate="{StaticResource GenderPopupTemplate}" ...>
The directly assigned local value always has higher precedence than any value from Style Setters (and other possible sources), so that the Setter has no effect. More details can be found here: Dependency Property Value Precedence.
Replace the direct assignment be another Style Setter:
<controls:MessageOverLay ...>
<controls:MessageOverLay.Style>
<Style TargetType="{x:Type controls:MessageOverLay}">
<Setter Property="MessageTemplate"
Value="{StaticResource GenderPopupTemplate}"/>
<Style.Triggers>
...
</Style.Triggers>
</Style>
</controls:MessageOverLay.Style>
...
</controls:MessageOverLay>
I have a Button control that I want to be able to reuse throughout project. Each time button enters a new state, a different image will be displayed. For now, I have Normal State and Pressed State.
Here's the XAML portion of the control:
<Button
x:Class="customImageButton.ImageButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<ContentControl Width="80">
<Grid>
<Image Name="Normal" Source="{Binding NormalState}"/>
<Image Name="Pressed" Source="{Binding PressedState}" Visibility="Hidden"/>
</Grid>
</ContentControl>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
<Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Here's the code-behind for the control:
namespace customImageButton
{
public partial class ImageButton : Button
{
public ImageButton()
{
this.InitializeComponent();
}
public ImageSource NormalState
{
get { return base.GetValue(NormalStateProperty) as ImageSource; }
set { base.SetValue(NormalStateProperty, value); }
}
public static readonly DependencyProperty NormalStateProperty =
DependencyProperty.Register("NormalState", typeof(ImageSource), typeof(ImageButton));
public ImageSource PressedState
{
get { return base.GetValue(PressedStateProperty) as ImageSource; }
set { base.SetValue(PressedStateProperty, value); }
}
public static readonly DependencyProperty PressedStateProperty =
DependencyProperty.Register("PressedState", typeof(ImageSource), typeof(ImageButton));
}
}
...and here is its use:
<local:ImageButton Content="CustomButton" HorizontalAlignment="Left"
VerticalAlignment="Top" NormalState="Resources/Normal.png"
PressedState="Resources/Pressed.png"/>
My problem is that the images I've provided are not displaying. The Build Action for both images is Resource and I have tried using absolute path; however, that provided the same result. What am I missing?
Two problems with the code as listed:
The bindings need to be TemplateBinding.
The TargetType should refer to the "ImageButton" type, not Button.
Like this:
<ControlTemplate
xmlns:local="clr-namespace:customImageButton"
TargetType="{x:Type local:ImageButton}">
<Grid>
<ContentControl Width="80">
<Grid>
<Image Name="Normal" Source="{TemplateBinding NormalState}"/>
<Image Name="Pressed" Source="{TemplateBinding PressedState}" Visibility="Hidden"/>
</Grid>
</ContentControl>
</Grid>
Note: The above builds and runs, but Visual Studio complains:
'ImageButton' ControlTemplate TargetType does not match templated type 'Button'.
I suggest putting the control template in its own Style in the Themes/Generic.xaml resource dictionary, rather than inline.
I am new in working with wpf and currently I am trying to do the following: I have created a simple ContenctControl (CtrpushPinContent) that contains a TextBlock:
<ContentControl x:Class="CtrpushPinContent" ...
<Grid x:Name="LayoutRoot" Background="{x:Null}">
<Border BorderThickness="3" Name="border1" CornerRadius="15" BorderBrush="#FF070707" Margin="0,0,0,0">
<Border BorderBrush="Silver" BorderThickness="3" Name="border2" CornerRadius="15" Background="#FF413E3E">
<TextBlock Name="textBlock1" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="4" Foreground="White" />
</Border>
</Border>
</Grid>
</ContentControl>
The cs file looks like this:
public partial class CtrpushPinContent : ContentControl
{
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Text",
typeof(string),
typeof(CtrpushPinContent),
new PropertyMetadata(string.Empty));
public string Text
{
get { return textBlock1.Text; }
set { textBlock1.Text = value; }
}
public CtrpushPinContent()
{
InitializeComponent();
}
}
On the main PhoneApplicationPage I try to do the following:
<phone:PhoneApplicationPage.Resources>
<Style TargetType="my:Pushpin" x:Key="PushpinStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="my:Pushpin">
<Grid x:Name="ContentGrid">
<StackPanel Orientation="Vertical">
<Grid Background="{x:Null}" HorizontalAlignment="Right" MinHeight="31" MinWidth="29">
<LJTileSources:CtrpushPinContent HorizontalAlignment="Right" Text="{TemplateBinding Content}" Margin="4" ContentTemplate="{TemplateBinding ContentTemplate}" />
</Grid>
<Image Source="/WifiHotSpot;component/Images/blackPinNoShadow.png" Width="54" Height="54" HorizontalAlignment="Center"></Image>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
<Grid>
<my:Map Margin="0,1,0,0" Name="map1" LogoVisibility="Collapsed" Height="576" CredentialsProvider="key" ZoomLevel="2">
<my:Pushpin Style="{StaticResource PushpinStyle}" Content="Test" Location="50.0863762,14.42814" PositionOrigin="BottomLeft"></my:Pushpin>
</my:Map>
</Grid>
However my solution is not working. I cannot see any effect of the
<my:Pushpin Style="{StaticResource PushpinStyle}" Content="Test" .../>
I believe the problem is somewhere in the style declaration:
<LJTileSources:CtrpushPinContent HorizontalAlignment="Right" Text="{TemplateBinding Content}" Margin="4" ContentTemplate="{TemplateBinding ContentTemplate}" />
because when I change it to
<LJTileSources:CtrpushPinContent HorizontalAlignment="Right" Text="TestText" Margin="4" ContentTemplate="{TemplateBinding ContentTemplate}" />
it displays the "TestText" as required.
In your case for solve this problem quickly you need to implement this:
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Text",
typeof(string),
typeof(CtrpushPinContent),
new PropertyMetadata(string.Empty, OnTextChanged));
public string Text
{
get { return textBlock1.Text; }
set { textBlock1.Text = value; }
}
private static void OnTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
((CtrpushPinContent)sender).textBlock1.Text = (string)e.NewValue;
}
public CtrpushPinContent()
{
InitializeComponent();
}
When you set text in Pushpin template:
<LJTileSources:CtrpushPinContent HorizontalAlignment="Right" Text="{TemplateBinding Content}"
Margin="4" ContentTemplate="{TemplateBinding ContentTemplate}" />
you don't set Text property in your control, you set value of dependency property CaptionProperty, because you registered it with name "Text". So when you set Text from xaml, you set exactly Caption property, not Text property of your control. So you need to create event of changing this dependency property for updating text in textBox1.