I am trying to display a text on a custome user control. I want that text to be passed via a mainview
this is the code I have:
MainView.axaml
<cc:Slot Grid.Row="0" Grid.Column="1" Dot="Number one"/>
<cc:Slot Grid.Row="0" Grid.Column="2" Dot="Number two"/>
This is my custom user control:
Slot.axaml
<UserControl xmlns="https://github.com/avaloniaui"
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:controls="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:cc="clr-namespace:Diagnostica.CustomControls;assembly=Diagnostica.CustomControls"
x:Class="Diagnostica.CustomControls.OmniSlot">
<Button>
<TextBlock Text="{Binding Dot}"/>
</Button>
</Grid>
</Button>
</UserControl>
and its .cs file"
Slot.axaml.cs
public string Dot
{
get => GetValue(DotProperty);
set => SetValue(DotProperty, value);
}
public static readonly StyledProperty<string> DotProperty =
AvaloniaProperty.Register<Slot, string>(nameof(Dot), defaultValue: "Black");
what i get like this is a disabled box. How can this get fixed?
View:
<Rectangle Stroke="{TemplateBinding DotColor}" StrokeThickness="2" Width="20" Height="20" Fill="{TemplateBinding DotColorBrush}" VerticalAlignment="Top" HorizontalAlignment="Right"/>
ViewModel:
public static readonly StyledProperty<string> DotColorProperty = AvaloniaProperty.Register<OmniSlotControl, string>(nameof(DotColor), "Red");
public string DotColor
{
get => GetValue(DotColorProperty);
set
{
SetValue(DotColorProperty, value);
DotColorBrush = Avalonia.Media.Brush.Parse(value);
}
}
I want to create some components and reuse them in different pages, put more than one in a page, etc.
For example, I want to create a component that contains an image, some text, etc. The position of the elements are fixed, but I will change the image, the text... I mean, in a same page I want to put three circles with different image and text...
What is the best way to do it? I've found UserControl, but I'm unable to call a method from another page to change something.
This is my component XAML
<UserControl
x:Class="aa.Components.CircularGraph"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Components"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid Name="view">
<Image Name="imageGraph" Source="../Assets/aa/circuloGris.png"
/>
<StackPanel Orientation="Vertical">
<TextBlock Name="firstLine" Text="1" FontFamily="Arial" FontSize="9"></TextBlock>
<TextBlock Name="secondLine" Text="2" FontFamily="Arial" FontSize="9"></TextBlock>
<TextBlock Name="thirdLine" Text="3" FontFamily="Arial" FontSize="9"></TextBlock>
</StackPanel>
</Grid>
</UserControl>
Its code:
public sealed partial class CircularGraph: UserControl {
public CircularGraph() {
this.InitializeComponent();
Height = 300;
Width = 400;
}
public void changeFirstLine(string var) {
firstLine.Text = var;
}
}
In other page I put:
<local:CircularGraph Name="circularGraph"/>
And I've tried to put this in .cs:
protected override void OnNavigatedTo(NavigationEventArgs e) {
circularGraph.changeFirstLine("aaa");
}
But I have an error: The name 'circularGraph' does not exits in the current context.
How can I do this?
Sorry if it's a simple question. I'm newbie at Windows phone.
Thank you very much!
Try x:Name instead of Name. "All x:Name means to XAML is generate a field to store the value in the code behind class."
<local:CircularGraph x:Name="circularGraph"/>
In WPF, what are the differences between the x:Name and Name attributes?
I want to show default image (some thing like brand icon) before original image is loaded from server. It is possible with out writing much code. Because I want same behavior in whole app.
or we need to create custom control for that. Please guide me!
If you are going to reuse it at a lot of different place it's probably easier to just create a CustomControl.
Here is a small user control which should do that:
<UserControl x:Class="PhoneApp1.ImageWithLoading"
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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480"
x:Name="myImageWithLoading">
<Grid x:Name="LayoutRoot" >
<Image x:Name="temporaryImage" Source="/Assets/Loading"/>
<Image Source="{Binding Source,ElementName=myImageWithLoading}" ImageOpened="RemoteImage_OnLoaded"/>
</Grid>
</UserControl>
public partial class ImageWithLoading : UserControl
{
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof (ImageSource), typeof (ImageWithLoading), new PropertyMetadata(default(ImageSource)));
public ImageSource Source
{
get { return (ImageSource) GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public ImageWithLoading()
{
InitializeComponent();
}
private void RemoteImage_OnLoaded(object sender, RoutedEventArgs e)
{
temporaryImage.Visibility = Visibility.Collapsed;
}
}
Another option might be to create a default style for Images in your default style page like so
<Style TargetType="Image">
<Setter Property="Source" Value="/Assets/Load.jpg"/>
</Style>
and just set the source when the image is ready
I have two very simple UserControls in a simple WinRT demo project. No Viewmodel--mostly just colored boxes for layout exploration. The first UserControl I created works fine. The second, very similar one, won't bind to any properties--it shows up as blank.
The first UserControl looks like this:
<UserControl
x:Class="Demo.SmallStartTile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Demo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="SmallStartTileUC"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid x:Name="SmallTileGrid"
Margin="0,0,8,8"
Background="{Binding Background, ElementName=SmallStartTileUC}"
>
<Rectangle
Stroke="{Binding BorderBrush, ElementName=SmallStartTileUC}"
Grid.RowSpan="2"
/>
<TextBlock x:Name="SmallTileTitle"
Text="{Binding TileText, ElementName=SmallStartTileUC}"
Style="{StaticResource SmallTileHeader}"/>
<Path x:Name="IconPath"
Style="{StaticResource SmallTileIcon}"
Data="{Binding TileIconPathData, ElementName=SmallStartTileUC}" />
</Grid>
</UserControl>
namespace Demo
{
public sealed partial class SmallStartTile : UserControl
{
public static DependencyProperty TileTextProperty = DependencyProperty.Register("TileText", typeof(string), typeof(SmallStartTile), new PropertyMetadata("tile content"));
public string TileText
{
get { return (string)GetValue(TileTextProperty); }
set { SetValue(TileTextProperty, value); }
}
public static DependencyProperty TileIconPathDataProperty = DependencyProperty.Register("TileIconPathData", typeof(string), typeof(SmallStartTile), new PropertyMetadata("F0"));
public string TileIconPathData
{
get { return (string)GetValue(TileIconPathDataProperty); }
set { SetValue(TileIconPathDataProperty, value); }
}
public SmallStartTile()
{
this.InitializeComponent();
}
}
}
And the second one, which I made just like the first one by clicking Add New Item and picking UserControl in Blend:
<UserControl
x:Class="Demo.SmallMediaTile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Demo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="SmallMediaTileUC"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid
Margin="0,0,8,8"
Background="{Binding Background, ElementName=SmallMediaTileUC}"
>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle
Stroke="{Binding BorderBrush, ElementName=SmallMediaTileUC}"
Grid.RowSpan="2"
/>
<Viewbox
Margin="30"
Child="{Binding Content, ElementName=SmallMediaTileUC}">
</Viewbox>
<TextBlock
Grid.Row="1"
Text="{Binding SourceText, ElementName=SmallMediaTileUC}"
Style="{StaticResource SmallMusicTileHeader}"/>
</Grid>
</UserControl>
namespace Demo
{
public sealed partial class SmallMediaTile : UserControl
{
public static DependencyProperty SourceTextProperty = DependencyProperty.Register("SourceText", typeof(string), typeof(SmallMediaTile), new PropertyMetadata("source"));
public string SourceText
{
get { return (string)GetValue(SourceTextProperty); }
set { SetValue(SourceTextProperty, value); }
}
public SmallMediaTile()
{
this.InitializeComponent();
}
}
}
I use the UserControl in the main Page like this:
<local:SmallMediaTile x:Name="Source1Tile"
Grid.Column="0" Grid.Row="0"
SourceText="Radio"
Background="Blue"
BorderBrush="Red">
<local:SmallMediaTile.Content>
<Canvas x:Name="radio_icon" Height="68" Width="34">
<Path Data="F1M299.6182,396.2988C299.6182,389.7208,297.0722,383.5548,292.4572,378.8398L288.6162,382.6758C292.2022,386.3718,294.1842,391.1778,294.1842,396.2988C294.1842,401.4238,292.2022,406.2368,288.6162,409.9328L292.4572,413.7738C297.0722,409.0538,299.6182,402.8808,299.6182,396.2988" Fill="White" Height="34.934" Canvas.Left="0" Stretch="Fill" Canvas.Top="16.501" Width="11.002"/>
<Path Data="F1M311.1738,396.2988C311.1738,386.6278,307.4348,377.5528,300.6788,370.6208L296.8258,374.4618C302.5658,380.3698,305.7398,388.0798,305.7398,396.2988C305.7398,404.5218,302.5658,412.2298,296.8258,418.1428L300.6788,421.9898C307.4348,415.0498,311.1738,405.9718,311.1738,396.2988" Fill="White" Height="51.369" Canvas.Left="8.21" Stretch="Fill" Canvas.Top="8.282" Width="14.348"/>
<Path Data="F1M322.7578,396.2988C322.7578,383.5298,317.8508,371.5348,308.9638,362.3388L305.1168,366.1748C312.9758,374.3538,317.3338,384.9778,317.3338,396.2988C317.3338,407.6208,312.9758,418.2488,305.1168,426.4268L308.9638,430.2748C317.8508,421.0698,322.7578,409.0798,322.7578,396.2988" Fill="White" Height="67.936" Canvas.Left="16.501" Stretch="Fill" Canvas.Top="0" Width="17.641"/>
</Canvas>
</local:SmallMediaTile.Content>
</local:SmallMediaTile>
The first one picks up all the properties and displays like I expect, but the second one only picks up the Viewbox content. I've looked through SO and been googling but can't figure out what the problem is. Sorry if this is longwinded.
Your root Grid is set as the Content of the UserControl while the Viewbox you have is trying to bind its Child property to the Content of the UserControl that is its ascendant. That is not allowed since the root Grid is already a parent of the UserControl and XAML controls can only exist in one place in the UI.
As noted, the problem is the UserControl's content can only be set once. When I bind the Viewbox Content to the UserControl content, the existing XAML is replaced. So, a blank box but for what I'm passing in. I guess to do what I had hoped, I'd need to make a custom control. Thanks for the help!
What I want to do is bind the text of a TextBlock to my custom ButtonSymbol property of the UserControl.
Here is the XAML for the UserControl. The Binding part for the TextBlock needs to be filled in.
<UserControl
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"
x:Class="Calculator.CalculatorButton"
d:DesignWidth="120" d:DesignHeight="80">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Image Source="buttonb#2x.png" Stretch="Fill"/>
<Button x:Name="InvisibleButton" Content="{Binding ButtonSymbol}" Margin="0,0,0,0" d:LayoutOverrides="Width, Height" BorderThickness="1" Click="InvisibleButton_Click"/>
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,0" TextWrapping="Wrap"
Text="{Binding ????????}"
VerticalAlignment="Top"/>
</Grid>
</UserControl>
And here is the CodeBehind:
namespace Calculator
{
public partial class CalculatorButton : UserControl
{
public string ButtonSymbol {get; set;}
public CalculatorButton()
{
// Required to initialize variables
InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
}
private void InvisibleButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
Debug.WriteLine(#"click");
Debug.WriteLine(ButtonSymbol);
// TODO: Add event handler implementation here.
}
}
}
Note that this is WP7 with Silverlight, and the RelativeSource class is not the same as in other versions.
You need to set the DataContext of the user control.
If you add this:
this.DataContext = this;
into the constructor or Loaded event of the user control you can then do this:
Text="{Binding ButtonSymbol}"
Note that you can also declaratively bind the DataSource of the XAML, this is just an easy programmatic way to do it.