How to set textwrapping in Button - winrt-xaml

did a search on internet, could not find the solution. I think I missed something for below code to make the text wrap:
<Button x:Name="btnCustomerAging" Background="Green" BorderBrush="Green" Foreground="White" FontSize="33" HorizontalAlignment="Left" Margin="662,106,0,0" Grid.Row="1" VerticalAlignment="Top" Height="213" Width="238">
<TextWrapping>
Customer Locations
</TextWrapping>
</Button>

This will work.
<Button x:Name="btnCustomerAging" Background="Green" BorderBrush="Green" Foreground="White" FontSize="33"
HorizontalAlignment="Left" Margin="662,106,0,0" Grid.Row="1" VerticalAlignment="Top" Height="213" Width="238">
<TextBlock Text="Customer Locations" TextWrapping="Wrap" />
</Button>

You can create your own WrapButton and use it in XAML like this:
<local:WrapButton x:Name="MyButton" Text="Text that will wrap"/>
This is the code for WrapButton:
public sealed class WrapButton : Button
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(WrapButton), new PropertyMetadata(string.Empty));
public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } }
public WrapButton()
{
var textBlock = new TextBlock { TextAlignment = TextAlignment.Center, TextWrapping = TextWrapping.Wrap };
textBlock.SetBinding(TextBlock.TextProperty, new Binding { Source = this, Path = new PropertyPath("Text") });
Content = textBlock;
}
}

Related

Unable to use FlexLayout in a BindableLayout with MAUI

I'm trying to use a FlexLayout in the DataTemplate section of a BindableLayout with MAUI. I'm using a StackLayout as a BindableLayout. However, the app does not even start because of an error that seems to come from the Xaml code. Everything is fine when I use a StackLayout or a Grid instead but I want to use a FlexLayout if possible. What am I doing wrong?
Here is a picture of the error:
XAML Error
Exception details 1
Exception details 2
The error message is "Élément introuvable" which means Unable to find element.
Here is the xaml code:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:tests="clr-namespace:Tests"
xmlns:components="clr-namespace:Tests.Components"
Shell.NavBarIsVisible="False"
x:Class="Tests.MainPage">
<StackLayout>
<StackLayout x:Name="Items">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="tests:Phone">
<FlexLayout>
<Image MaximumHeightRequest="150" Source="{Binding Image}"/>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Price}"/>
<Label Text="{Binding Year}"/>
</FlexLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</ContentPage>
Here is the .cs code:
public partial class MainPage : ContentPage {
private ObservableCollection<Phone> phones = new();
public MainPage() {
InitializeComponent();
InitPhoneCollection();
}
private void InitPhoneCollection() {
Phone phone1 = new Phone {
Name = "iPhone",
Price = 100,
Year = "2019",
Image = "iphone.jpg"
};
Phone phone2 = new Phone {
Name = "Samsung",
Price = 150,
Year = "2021",
Image = "samsung.jpg"
};
Phone phone3 = new Phone {
Name = "Blackberry",
Price = 200,
Year = "2022",
Image = "blackberry.jpg"
};
phones.Add(phone1);
phones.Add(phone2);
phones.Add(phone3);
BindableLayout.SetItemsSource(Items, phones);
}
}
Thanks
I tried a StackLayout and a Grid instead but for best results but I would prefer a FlexLayout.
This is a known issue that being tracked in the links below, you can follow up there.
https://github.com/dotnet/maui/issues/9905
https://github.com/dotnet/maui/issues/11909
https://github.com/dotnet/maui/issues/9075
As an alternative workaround, you can use StackLayout or Grid instead of FlexLayout like below:
<StackLayout x:Name="Items">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="tests:Phone">
<StackLayout>
<Image MaximumHeightRequest="150" Source="{Binding Image}"/>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Price}"/>
<Label Text="{Binding Year}"/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>

modifier the Foreground color when Hover on a stackPanel Universal app

I have a splitview,that contains StackPanels,I want to define a style which modify the color when hover in each of those StackPanels,is this possible?
this is my code:
<StackPanel Orientation="Horizontal" Style="{Binding Source={StaticResource HyperlinkPointerOverForegroundThemeBrush}}" >
<Button x:Name="MenuButton1"
Width="50" Height="50" Background="Transparent">
<Button.Content>
<Image Source="images/chercher.png"></Image>
</Button.Content>
</Button>
<TextBlock Text="Resultats" FontSize="18" VerticalAlignment="Center" Foreground="#727271"/>
</StackPanel>
and I have defined the styles like that:
<SolidColorBrush x:Key="HyperlinkButtonBackgroundThemeBrush" Color="#e6e6e6" />
<SolidColorBrush x:Key="HyperlinkButtonBorderThemeBrush" Color="#e6e6e6" />
<SolidColorBrush x:Key="HyperlinkDisabledThemeBrush" Color="#e6e6e6" />
<SolidColorBrush x:Key="HyperlinkForegroundThemeBrush" Color="#e6e6e6" />
<SolidColorBrush x:Key="HyperlinkPointerOverForegroundThemeBrush" Color="#e6e6e6" />
<SolidColorBrush x:Key="HyperlinkPressedForegroundThemeBrush" Color="#e6e6e6" />
but when I hover,none of the StackPanels Foreground have changed
thanks for help
I don't think you can do that only with style. But, if you really want to use a style, you can combine with a behavior.
The behavior can use PointerEntered and PointerExited events to set a new Background. Next, the behavior can be setted in your style.
In order to implements this type of solution, you have to add the Behaviors SDK extensions (go to add references > Universal Windows > Extensions).
The definition of the behavior (for example) :
public class HoverBehavior : DependencyObject, Microsoft.Xaml.Interactivity.IBehavior
{
private Panel _associatedObject;
private Brush _baseBrush;
public Brush HoverBrush
{
get { return (Brush)GetValue(HoverBrushProperty); }
set { SetValue(HoverBrushProperty, value); }
}
public static readonly DependencyProperty HoverBrushProperty =
DependencyProperty.Register("HoverBrush", typeof(Brush), typeof(HoverBehavior), new PropertyMetadata(null));
public Brush DefaultBrush
{
get { return (Brush)GetValue(DefaultBrushProperty); }
set { SetValue(DefaultBrushProperty, value); }
}
public static readonly DependencyProperty DefaultBrushProperty =
DependencyProperty.Register("DefaultBrush", typeof(Brush), typeof(HoverBehavior), new PropertyMetadata(null));
public DependencyObject AssociatedObject
{
get { return _associatedObject; }
}
public void Attach(DependencyObject associatedObject)
{
_associatedObject = associatedObject as Panel;
if (_associatedObject != null)
{
_baseBrush = _associatedObject.Background;
if (_associatedObject != null)
{
_associatedObject.PointerEntered += _associatedObject_PointerEntered;
_associatedObject.PointerExited += _associatedObject_PointerExited;
}
}
}
private void _associatedObject_PointerExited(object sender, PointerRoutedEventArgs e)
{
if (_associatedObject != null)
_associatedObject.Background = HoverBrush;
}
private void _associatedObject_PointerEntered(object sender, PointerRoutedEventArgs e)
{
if (_associatedObject != null)
_associatedObject.Background = DefaultBrush ?? _baseBrush;
}
public void Detach()
{
_associatedObject.PointerEntered -= _associatedObject_PointerEntered;
_associatedObject.PointerExited -= _associatedObject_PointerExited;
}
}
In the xaml, you have to add a "using" for the Interactivity namespace :
<Page xmlns:i="using:Microsoft.Xaml.Interactivity" />
And, you can define a new style (named SpStyle for example) :
<Style TargetType="StackPanel"
x:Key="SpStyle">
<Setter Property="i:Interaction.Behaviors">
<Setter.Value>
<i:BehaviorCollection>
<local:HoverBehavior DefaultBrush="Yellow"
HoverBrush="Green" />
</i:BehaviorCollection>
</Setter.Value>
</Setter>
</Style>
The HoverBrush property of the behavior is the color of the StackPanel when the mouse pointer is hover the StackPanel, and DefaultBrush (can be unset) is the color of the StackPanel when the mouse pointer is not hover the StackPanel.

i need a list view example program in windows phone 8

I need to create a list view in Windows Phone 8 to display the following debug information (what follows is my code that currently displays messages in Debug.WriteLine).
contacts.SearchCompleted += (s, e) =>
{
foreach (var contact in e.Results)
{
Debug.WriteLine(contact.DisplayName + " - " + contact.PhoneNumbers.First().PhoneNumber);
textAddressLine1.Text= contact.DisplayName + " - " + contact.PhoneNumbers.First().PhoneNumber;
}
};
contacts.SearchAsync("", FilterKind.DisplayName, null);
Have any of you created a listview on this platform and can help me?
Here's the simplest example I could come up with.
I've also added handling for contacts without any phone numbers.
xaml:
<phone:PhoneApplicationPage
x:Class="so17564250.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="SO 17564250" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="listview example" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector ItemsSource="{Binding}" />
</Grid>
</Grid>
</phone:PhoneApplicationPage>
cs:
namespace so17564250
{
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Phone.Controls;
using Microsoft.Phone.UserData;
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
this.DisplayedContacts = new ObservableCollection<string>();
this.DataContext = this.DisplayedContacts;
var contacts = new Contacts();
contacts.SearchCompleted += (s, e) =>
{
foreach (var contact in e.Results)
{
this.DisplayedContacts.Add(contact.DisplayName + " - " +
(contact.PhoneNumbers.Any()
? contact.PhoneNumbers.First().PhoneNumber
: string.Empty));
}
};
contacts.SearchAsync(string.Empty, FilterKind.DisplayName, null);
}
public ObservableCollection<string> DisplayedContacts { get; set; }
}
}

What are the best practices to dynamically create views and add controls to view using MVVM pattern

Can anyone give out the best practices for playing around with controls at runtime such as creating a new view,adding views inside a view,adding controls to containers using MVVM pattern without breaking mvvm pattern??
I am using MVVMlight toolkit..
please help me out in this regard..
Thanks in advance......
This post discusses the strategies for creating views (dialogs) from your view models.
Edit:
From your comment I take it that you got an user interface that has an add and delete button. The add button should add an item (type ?) to a ItemsControl ... hope that's correct.
So, how would I do this, well I would create a view model that has an ObservableCollecion<ItemViewModel>. The ItemViewModle is the view mode that represents the item that should be added to the ItemsControl (so in your case the view model backing your "rangeView").
Then I would add two commands that handle the addition and deletion of items. Both commands just add/remove ItemViewModels from your collection.
To show the items in the view I would bind the ItemControl.ItemsSource property to the collection in your main view model (i.e. the one holding the ItemViewModel instances). The I would supply an ItemTemplate to render the items on the screen.
Ok, here is an example of what I think you are trying to do (at least conceptionally). Complete Source Code here. In the example I used a ListBox as it allows me easily to determine which item is selected, this depends on your szenario. Also note that you have complete freedom to customize the Template, the ItemPanelTemplate, and DataTemplate to fit your needs. You can even use this approacht to create PanoramaPages in WP7!
2nd edit: ItemsControl does not have a SelectedItem property. To get to it you have to use a control inheriting from Selector (e.g. a ListBox as I did) or you can use the Selector directly.
ItemViewModel:
public class ItemViewModel : ViewModelBase
{
#region [Name]
public const string NamePropertyName = "Name";
private string _name = null;
public string Name {
get {
return _name;
}
set {
if (_name == value) {
return;
}
var oldValue = _name;
_name = value;
RaisePropertyChanged(NamePropertyName);
}
}
#endregion
}
MainViewModel:
public class MainViewModel : ViewModelBase
{
public MainViewModel() {
if (IsInDesignMode) {
this.Items = new ObservableCollection<ItemViewModel>(Enumerable.Range(0, 10).Select((x, i) => new ItemViewModel() { Name = "Design Time Item " + i }));
} else {
// Code runs "for real"
}
}
#region [AddCommand]
private RelayCommand _addCommand;
public RelayCommand AddCommand {
get {
return _addCommand ?? (_addCommand = new RelayCommand(
() => {
this.Items.Add(new ItemViewModel() { Name = "New item - " + DateTime.Now });
}
));
}
}
#endregion
#region [DeleteCommand]
private RelayCommand _deleteCommand;
public RelayCommand DeleteCommand {
get {
return _deleteCommand ?? (_deleteCommand = new RelayCommand(
() => {
this.Items.Remove(this.SelectedItem);
},
() => { return this.SelectedItem != null; }
));
}
}
#endregion
#region [Items]
public const string ItemsPropertyName = "Items";
private ObservableCollection<ItemViewModel> _items = new ObservableCollection<ItemViewModel>();
public ObservableCollection<ItemViewModel> Items {
get {
return _items;
}
set {
if (_items == value) {
return;
}
var oldValue = _items;
_items = value;
RaisePropertyChanged(ItemsPropertyName);
}
}
#endregion
#region [SelectedItem]
public const string SelectedItemPropertyName = "SelectedItem";
private ItemViewModel _selectedItem = null;
public ItemViewModel SelectedItem {
get {
return _selectedItem;
}
set {
if (_selectedItem == value) {
return;
}
var oldValue = _selectedItem;
_selectedItem = value;
RaisePropertyChanged(SelectedItemPropertyName);
// important in SL to notify command that can execute has changed !
this.DeleteCommand.RaiseCanExecuteChanged();
}
}
#endregion
}
MainPage.xaml
<UserControl
x:Class="MvvmLight1.MainPage"
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"
mc:Ignorable="d"
Height="300"
Width="300"
DataContext="{Binding Main, Source={StaticResource Locator}}"
>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<!-- we are dealing with ItemViewModels now -->
<Border BorderThickness="0,0,0,1" BorderBrush="Gray" Padding="10,5">
<TextBlock Text="{Binding Name}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Margin="5,10" Content="Add" Command="{Binding AddCommand}" Width="70"/>
<Button Margin="5,10" Content="Delete" Command="{Binding DeleteCommand}" Width="70"/>
</StackPanel>
</Grid>
</UserControl>

Notification window in case of any operation in C: drive

I have created a sample for Notification window in silverlight4.
The issue i'm facing is that i want to show notification window whenever any operation(say file copied or deleted) is performed in my windows C: drive.
Since System.IO.FileSystemWatcher class (COM+ componenet) cannot be used in silverlight, so i found a way out using an AutomationFactory, it works like charm for me as long as i am using message box to show notification or default notification window but not in case of my own customnotification window.. :(
The code is like this -
new Thread(() =>
{
using (dynamic SWbemLocator = AutomationFactory.CreateObject("WbemScripting.SWbemLocator"))
{
SWbemLocator.Security_.ImpersonationLevel = 3;
SWbemLocator.Security_.AuthenticationLevel = 4;
dynamic IService = SWbemLocator.ConnectServer(".", #"root\cimv2");
string fileSystemWatcherQuery =
#"SELECT * FROM __InstanceOperationEvent WITHIN 3 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent= 'Win32_Directory.Name=""c:\\\\""'";
dynamic monitor = IService.ExecNotificationQuery(fileSystemWatcherQuery);
Dispatcher.BeginInvoke(() => MessageBox.Show(#"Now listening to file changes on c:\"));
while (true)
{
dynamic EventObject = monitor.NextEvent();
string eventType = EventObject.Path_.Class;
string path = EventObject.TargetInstance.PartComponent;
Dispatcher.BeginInvoke((Action)delegate
{
System.Windows.NotificationWindow notify = new System.Windows.NotificationWindow();
notify.Height = 74;
notify.Width = 329;
CustomNotification custom = new CustomNotification();
custom.Header = "FileSystemWatcher";
custom.Text = eventType + ":" + path;
custom.Width = notify.Width;
custom.Height = notify.Height;
custom.Closed += new EventHandler<EventArgs>(custom_Closed);
notify.Content = custom;
notify.Show(5000);
});
Dispatcher.BeginInvoke(() => MessageBox.Show(eventType + ": " + path));
}
}
}).Start();
Whenever i copied the file or delete a file from my C:, a message box appears and notification window do appears but the content is entirely blank. If i use default notification window in place of my own CustomNotification it works fine.
What i am guessing is, it has something related to threading, not sure though.. ??
CustomNotification is a class which derives from ContentConrol class and have two dependency properties namely "Header" & "Text". The control template for this i have declared in different xaml file like this -
<Style TargetType="local:CustomNotification">
<Setter.Value>
<ControlTemplate TargetType="local:CustomNotification">
<Border BorderBrush="Black" BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="7"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFB9B9CC"/>
<GradientStop Color="#FF9191AB" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid Grid.Row="1">
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFEDEDF5" Offset="0"/>
<GradientStop Color="#FFC4C3D7" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Button x:Name="closeButton" Grid.Column="2" VerticalAlignment="Top" Margin="1, 3" Width="16" Height="13">
<Button.Template>
<ControlTemplate TargetType="Button">
<Image Source="x.png"/>
</ControlTemplate>
</Button.Template>
</Button>
<StackPanel Grid.Column="1" Margin="5, 7">
<TextBlock Text="{TemplateBinding Header}" FontFamily="Verdana" FontWeight="Bold" FontSize="11"/>
<TextBlock Text="{TemplateBinding Text}" FontFamily="Verdana" FontSize="11" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here goes my CustomNotification class code -
public class CustomNotification : ContentControl
{
public CustomNotification()
{
this.DefaultStyleKey = typeof(CustomNotification);
}
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
"Header",
typeof(string),
typeof(CustomNotification),
new PropertyMetadata(OnHeaderPropertyChanged));
/// <summary>
/// Gets or sets a value that indicates whether
/// the <see cref="P:System.Windows.Controls.Label.Target" /> field is required.
/// </summary>
public string Header
{
get
{
return (string)GetValue(CustomNotification.HeaderProperty);
}
set
{
SetValue(CustomNotification.HeaderProperty, value);
}
}
private static void OnHeaderPropertyChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(CustomNotification),
new PropertyMetadata(OnTextPropertyChanged));
/// <summary>
/// Gets or sets a value that indicates whether
/// the <see cref="P:System.Windows.Controls.Label.Target" /> field is required.
/// </summary>
public string Text
{
get
{
return (string)GetValue(CustomNotification.TextProperty);
}
set
{
SetValue(CustomNotification.TextProperty, value);
}
}
private static void OnTextPropertyChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Button closeButton = GetTemplateChild("closeButton") as Button;
if (closeButton != null)
{
closeButton.Click += new RoutedEventHandler(closeButton_Click);
}
}
public event EventHandler<EventArgs> Closed;
void closeButton_Click(object sender, RoutedEventArgs e)
{
EventHandler<EventArgs> handler = this.Closed;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
I assume your CustomNotification class is just a user control (i.e. inherits directly from UserControl)? Assuming so, this line:
notify.Content = tb;
is wrong. I don't know what tb is, but it should be:
notify.Content = custom;
Then you'll see the content.
Note that you have to be careful to not try and show a notification whilst another one is currently being displayed. You'll get an exception, so you'll need to keep track of this.
Hope this helps...
Chris Anderson

Resources