I've been trying to bind two textboxes to a single label so the label always update depending on the content of two textboxes. However without luck. I managed to solve how to bind a single one.
by using
Content="{Binding Text,ElementName=PersonName,UpdateSourceTrigger=PropertyChanged}"
So it looks like this
<UserControl x:Class="FitTracker.CreateTrackItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FitTracker"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox Name="PersonName" HorizontalAlignment="Left" Height="23" Margin="10,77,0,0" TextWrapping="Wrap" Text="Name" VerticalAlignment="Top" Width="280" />
<TextBox Name="PersonLevel" HorizontalAlignment="Left" Height="23" Margin="10,105,0,0" TextWrapping="Wrap" Text="Level" VerticalAlignment="Top" Width="280"/>
<Label Name="TrackDetails" Content="{Binding Text,ElementName=PersonName,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,133,0,0" VerticalAlignment="Top" Width="280" FontWeight="Bold" Background="#00000000" Foreground="White" />
</Grid>
</UserControl>
However I cannot do it with two text boxes. any ideas or guides that could help me on the right path.
I've been searching around for some hours now.
Use a MultiBinding:
<TextBox x:Name="PersonName"/>
<TextBox x:Name="PersonLevel"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Name: {0}, Level: {1}">
<Binding Path="Text" ElementName="PersonName"/>
<Binding Path="Text" ElementName="PersonLevel"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
You can use a TextBlock with multiple Run elements:
<TextBox x:Name="PersonName"/>
<TextBox x:Name="PersonLevel"/>
<TextBlock>
<TextBlock.Inlines>
<Run Text="{Binding Text, ElementName=PersonName}"/>
<Run Text="{Binding Text, ElementName=PersonLevel}"/>
</TextBlock.Inlines>
<TextBlock>
You can also declare a new property, for example
public string JoinedProps {get {return PersonName+ PersonLevel;}}
Do not forget to notify JoinedProps' property change on both of the PersonName
and PersonLevel fields
Related
There is an icon that I want to always be visible, but I want the tooltip to be conditionally visible. Here is the code that I currently have:
<TextBlock Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
FontSize="15"
Visibility="{Binding IsConnected, Converter={StaticResource BooleanToVisibilityConverter}}">
<fa:ImageAwesome Icon="{Binding Path=BatteryLevelIcon, UpdateSourceTrigger=PropertyChanged}"
Height="20"
Width="20"
Foreground="Green"
Visibility="{Binding IsConnected, Converter={StaticResource BooleanToVisibilityConverter}}" />
<ToolTipService.ToolTip>
<TextBlock Visibility="{Binding IsCharging, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}%">
<Binding Path="BatteryPercentage" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</ToolTipService.ToolTip>
</TextBlock>
So, I want the tooltip to only show up when IsCharging is false. The issue that I am having is that because the Visibility property is on the tooltip textblock instead of the tooltip itself, setting it to not visible only gives me a empty tooltip, instead of the tooltip not appearing at all. I have tried defining the content of the tooltip (textblock) in UserControls.Resources and then setting the textblock and IsEnabled, but it gave me the error:
a value of type tooltipservice cannot be added to a collection or dictionary of type inlinecolection
It doesn't seem there is an easy way to set the visibility for the tooltip. If anyone has any suggestions it would be greatly appreciated!
You could use ToolTipService.IsEnabled property for the purpose
ToolTipService.IsEnabled="{Binding IsToolTipVisible}"
Where IsToolTipVisible Where is the View Model property which dictates where to enable the tooltip
Complete Code
<TextBlock Grid.Row="2" ToolTipService.IsEnabled="{Binding IsToolTipVisible}"
Grid.Column="0"
VerticalAlignment="Center"
FontSize="15"
Visibility="{Binding IsConnected, Converter={StaticResource BooleanToVisibilityConverter}}">
<fa:ImageAwesome Icon="{Binding Path=BatteryLevelIcon, UpdateSourceTrigger=PropertyChanged}"
Height="20"
Width="20"
Foreground="Green"
Visibility="{Binding IsConnected, Converter={StaticResource BooleanToVisibilityConverter}}" />
<ToolTipService.ToolTip>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}%">
<Binding Path="BatteryPercentage" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</ToolTipService.ToolTip>
</TextBlock>
I have a strange behaviour using ObjectDataProvider. I need to bind a TextBlock with ToString method but, when I enter in method my properties are wrong.
This is my simple ObjectDataProvider:
<Window.Resources>
<ObjectDataProvider x:Key="ToString" MethodName="ToString" ObjectType="{x:Type entities:Season}" />
</Window.Resources>
And this is my ListView:
<ListView Grid.Row="2" Name="lvSeasons" HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Source={StaticResource ToString}}" VerticalAlignment="Center" />
<Button Grid.Column="1" VerticalAlignment="Center" Background="Transparent" BorderBrush="Transparent" Click="btDeleteSeason_Click">
<TextBlock FontFamily="{StaticResource FontAwesome}" Text="" FontSize="20" Foreground="Red" HorizontalAlignment="Center" />
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My method simply concat two properties:
public override string ToString()
{
return StartYear + "/" + EndYear;
}
In debug I can see that start and end year are always 0. If I bind my TextBlock using {Binding StartYear} it's correct and value is 2019.
Where can the problem be?
You do not need an ObjectDataProvider. Just write
<TextBlock Text="{Binding}" ... />
WPF will call the ToString method by default.
You do not even need to override ToString when you use a MultiBinding with an appropriate StringFormat:
<TextBlock ...>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}/{1}">
<Binding Path="StartYear "/>
<Binding Path="EndYear "/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
I want to create a pivot, with a DataBinding to a List of PivotItems.
Each of these items should be surrounded by a ScrollViewer.
Unfortunately it doesn't work the way I was thinking....
My code:
MainPage:
<Page
x:Class="PivotSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PivotSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot Title="Pivot" SelectedItem="{Binding CurrentPivotItem, Mode=TwoWay}" ItemsSource="{Binding PivotItems}">
<Pivot.ItemTemplate>
<DataTemplate>
<ScrollViewer>
<UserControl Content="{Binding Content}"/>
</ScrollViewer>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
</Grid>
UserControl (the second UserControl is the same):
<UserControl
x:Class="PivotSample.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PivotSample"
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="400">
<StackPanel Background="Yellow">
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Test" FontSize="30" HorizontalAlignment="Center"/>
</StackPanel>
ViewModel:
public class ViewModelMainPage : ViewModelBase
{
private IList<PivotItem> _pivotItems;
private PivotItem _currentPivotItem;
public IList<PivotItem> PivotItems
{
get { return _pivotItems; }
set { _pivotItems = value; }
}
public PivotItem CurrentPivotItem
{
get { return _currentPivotItem; }
set
{
OnPropertyChanged(nameof(CurrentPivotItem));
_currentPivotItem = value;
}
}
}
When I start the project comes following message: "The program '[2940] name.exe' has exited with code -1 (0xffffffff).
But when I replace the ScrollViewer with a Grid or StackPanel it will works but then I won't see all of my PivotItem.
Any ideas?
(Putting a new answer, as the question has changed it's context.)
Looks like the Pivot Control screws up, if you use a list of PivotItems at it'
s ItemsSource.
Anyway: That's not the way DataBindings are intended.
As the name suggests, you bind to Data, not to controls or UI Elements. PivotItems are UI Controls (although they are more of a logical than a visual representation) and should not be part of your ViewModel.
Just change the type in your ViewModel to some actual data (a List of String, Object, or whatever classes you create) and it works fine
Alternatively, if you want to place a fixed content inside a Pivot Control, you don't need to bind it at all and you can just place the PivotItems directly in Xaml:
<Pivot>
<PivotItem Header="First Item">
<!-- your content display here -->
</PivotItem>
<PivotItem Header="Secont Item">
<!-- your content display here -->
</PivotItem>
</Pivot>
(Outdated, as question was updated)
You can only set ItemControls as ItemsPanelTemplate and the Scrollviewer ist not an ItemsControl, but a ContentControl (it only wraps a single child and does not display multiple items).
Also, ItemsPanelTemplate is the wrong target for what you are trying to achieve: If you want to change the content of the PivotItems inside the Pivot, just set the regular ItemTemplate.
<Pivot>
<Pivot.ItemTemplate>
<DataTemplate>
<ScrollViewer>
<!-- your content display here -->
</ScrollViewer>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
i do have a problem with binding the visibility of my usercontrol.
The binding to a Dependency Property of type Visibility works fine and the correct value (in this case Collapsed) is held by the DP. The content of my Grid within the UserControl is set to collapsed, but the hole control doesnt collapse. It still keeps the space occupied defined by with and heigth, as referenced in the xaml.
EDIT: i found out, that the problem is that i set width and height in the xaml where i reference my usercontrol. if i don't do this, the control collapses correct (therefore binding works fine). But i need to set width and heigth in case the usercontrol is visible.
Any idea how i can solve this problem?
<my:MenuButtonBase x:Class="bxSuite.Controls.MenuButtonLarge"
xmlns:my="clr-namespace:bxSuite.Controls"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Background="Black"
>
<Grid Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ButtonVisibility}" >
<StackPanel>
<Image Source="{Binding ButtonImageSource}" Margin="5,10,5,5" Width="48" Height="48" VerticalAlignment="Top" HorizontalAlignment="Center" />
<TextBlock Text="{Binding FunctionHeader}" Foreground="White" TextWrapping="Wrap" TextAlignment="Center" Padding="5,5,5,5" FontSize="12" />
</StackPanel>
</Grid>
</my:MenuButtonBase>
In XAML i reference my usercontrol like this (where the Converter produces the visibility-state correctly):
<my:MenuButtonLarge Name="btnInEuqipment" ButtonVisibility="{Binding Path=User, Converter={StaticResource ConverterUserRightVisibility}, ConverterParameter=5}" VerticalAlignment="Top" FunctionHeader="{lex:Loc Key=MenuButton_InEquipment}" Width="130" ButtonImageSource="/bxSuite.RolloutManager;component/Images/inequipment_48x48.png" BackgroundEnabled="#FF0694FD" BackgroundHover="#FF0072C6" MenuButtonClick="btnInEuqipment_MenuButtonClick" Height="95" Margin="5,10,0,0" />
Try set the visibility of the user control instead of the grid, should work.
Your code should be like this.
<my:MenuButtonBase x:Class="bxSuite.Controls.MenuButtonLarge"
xmlns:my="clr-namespace:bxSuite.Controls"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ButtonVisibility}"
Background="Black">
<Grid>
<StackPanel>
<Image Source="{Binding ButtonImageSource}"
Margin="5,10,5,5"
Width="48"
Height="48"
VerticalAlignment="Top"
HorizontalAlignment="Center" />
<TextBlock Text="{Binding FunctionHeader}"
Foreground="White"
TextWrapping="Wrap"
TextAlignment="Center"
Padding="5,5,5,5"
FontSize="12" />
</StackPanel>
</Grid>
Dont forget to update the RelativeSource of your bind.
I got a string Properties.Settings.Default.myString and two TextBoxes
<TextBox x:Name="textBox1" Text="{Binding myString}"/>
<TextBox x:Name="textBox2" Text="{Binding myString}"/>
When I type text into textBox1 and change Focus, the text in textBox2 is updated with the text I just entered in textBox1.
What confuses me is that Properties.Settings.Default.myString never updates with the text I enter in either of the TextBoxes. I did confirm this by inspecting myStringin the debugger after changing it.
My question is, why this change in the textBox is not reflected in the bound variable myString?
Complete XAML (WPF-App):
<Window
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:textBoxDataBinding"
xmlns:Properties="clr-namespace:textBoxDataBinding.Properties" x:Class="textBoxDataBinding.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="212" Width="318">
<Window.DataContext>
<Properties:Settings/>
</Window.DataContext>
<Grid>
<TextBox x:Name="textBox1" Text="{Binding myString}"/>
<TextBox x:Name="textBox2" Text="{Binding myString}"/>
<!-- Button does: textBlock.Text = Properties.Settings.Default.myString; -->
<Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="10,157,0,0" VerticalAlignment="Top" Width="75" Click="button1_Click"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="90,161,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
</Grid>
EDIT
You are not binding to the Default singleton settings, you are creating a new set of Settings. What you need to bind to is Settings.Default singleton instance.
E.g.
<Window DataContext="{x:Static properties:Settings.Default}">
Alternative solution:
<TextBox x:Name="textBox1" Text="{Binding Default.myString}"/>
<TextBox x:Name="textBox2" Text="{Binding Default.myString}"/>
First answer for historical reason:
You need to bind to teh Defaul properties
You need to make sure either
The DataContext is your Properties.Settings.Default object.
Make the source of the binding as Properties.Settings.Default
This works for me:
<StackPanel>
<TextBox Text="{Binding Path=myStrring,Source={x:Static properties:Settings.Default}}"></TextBox>
<TextBox Text="{Binding Path=myStrring,Source={x:Static properties:Settings.Default}}"></TextBox>
</StackPanel>
Or cleaner syntax:
<Window x:Class="WpfApplication1.SO29048483"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:properties="clr-namespace:WpfApplication1.Properties"
Title="SO29048483" Height="300" Width="300">
<StackPanel DataContext="{x:Static properties:Settings.Default}">
<TextBox Text="{Binding myStrring}" />
<TextBox Text="{Binding myStrring}" />
</StackPanel>
</Window>
And if you want to udpate it before lose focus:
<TextBox Text="{Binding myStrring, UpdateSourceTrigger=PropertyChanged}" />