I have a TextBox in my Windows Phone application. It seems only the upper half of the TextBox is clickable to edit the Text. I need the whole TextBox to be clickable.
Why is this?
<Grid x:Name="FolderNameGrid">
<TextBlock Text="{Binding SelectedPostbox.LabelToUpper}"
Style="{StaticResource PageTitleTextBlockStyle}"
Visibility="{Binding IsInSearchMode, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=!}" />
<TextBox x:Name="SearchTextBox"
Margin="20,10,20,10"
KeyDown="SearchTextBox_OnKeyDown"
TextChanged="SearchTextBox_OnTextChanged"
GotFocus="SearchTextBox_GotFocus"
PlaceholderText="{Binding TextSource, Converter={StaticResource Language}, ConverterParameter=Module-Messages-Search, FallbackValue=Module-Messages-Search}"
Visibility="{Binding IsInSearchMode, Converter={StaticResource BoolToVisibilityConverter}}" />
</Grid>
Try adding RowDefinitions to your grid. The 2 controls are overlapping now.
e.g.
<Grid x:Name="FolderNameGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding SelectedPostbox.LabelToUpper}"
Style="{StaticResource PageTitleTextBlockStyle}"
Visibility="{Binding IsInSearchMode, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=!}" />
<TextBox Grid.Row="1"
x:Name="SearchTextBox"
Margin="20,10,20,10"
KeyDown="SearchTextBox_OnKeyDown"
TextChanged="SearchTextBox_OnTextChanged"
GotFocus="SearchTextBox_GotFocus"
PlaceholderText="{Binding TextSource, Converter={StaticResource Language}, ConverterParameter=Module-Messages-Search, FallbackValue=Module-Messages-Search}"
Visibility="{Binding IsInSearchMode, Converter={StaticResource BoolToVisibilityConverter}}" />
</Grid>
Related
I have a WPF app and I am trying to Automate it using FlaUI. I am facing a problem with the DxTabControl. I have provided Automation IDs to the DxTabControl. I am using DXTabControl.ItemHeaderTemplate to generate TabItems dynamically.
According to DevExpress Team, The DXTabControl.ItemHeaderTemplate doesnt support AutoamtionPeer so a custom implementation has been added to override its default behaviour.
Now, I am able to see the TabControl and the TabItems in the Inspect.exe.
Now , my requirement is to Access the currently selected Tabitem and find the CloseButton using the AutoamtionID mentioned in the XAML below and close it. Pasting below the line again. As there would be multiple TabItems generated, I am unable to get the Currently active/Selected TabItem .
The XAML is below
<dx:DXTabControl AutomationProperties.AutomationId="ViewsParentTabControl"
MaxWidth="4000"
MaxHeight="4000"
Margin="1,0,-1,0"
Focusable="False"
ItemsSource="{Binding OpenViews}"
SelectedIndex="{Binding SelectedTabIndex}"
TabContentCacheMode="CacheTabsOnSelecting">
<dx:DXTabControl.ItemHeaderTemplate>
<DataTemplate DataType="viewModels1:OpenViewDefinitionViewModel">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Name="CreatedViewName"
MaxWidth="100"
Text="{Binding Data.ViewDefinition.Name}"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding DisplayName}" />
<TextBlock Grid.Row="0" Grid.Column="1"><Run Text=" [" /><Run Text="{Binding ItemsCount, FallbackValue=0, Mode=OneWay}" /><Run Text="]" /></TextBlock>
<controls2:ProgressIndicator AutomationProperties.AutomationId="ProgressCurrentView"
Grid.Row="0"
Grid.Column="3"
Width="14"
Margin="4,0,0,0"
VerticalAlignment="Center"
CircleBorder="{StaticResource ListBoxItem.Foreground}"
CircleFill="{StaticResource ListBoxItem.Foreground}"
IndicatorEnabled="{Binding IsDataLoading}" />
<Button AutomationProperties.AutomationId="CloseCurrentViewButton"
Grid.Row="0"
Grid.Column="2"
Width="10"
Height="10"
Margin="10,1,0,0"
Padding="0"
HorizontalAlignment="Right"
BorderThickness="0"
Command="{Binding DataContext.CloseItemCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dx:DXTabControl}}"
CommandParameter="{Binding}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Close">
<Path
Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z"
Fill="White"
Stretch="Fill" />
</Button>
</Grid>
</DataTemplate>
</dx:DXTabControl.ItemHeaderTemplate>
<dx:DXTabControl.ItemTemplate>
<DataTemplate DataType="viewModels1:OpenViewDefinitionViewModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:VoyagesGridControl />
<local:VoyageValidationUserControl
Grid.Row="1"
Grid.Column="0"
MinHeight="100"
MaxHeight="300"
Visibility="{Binding Path=IsVoyageValidationShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<local:VoyageHistoryUserControl
Grid.Row="2"
Grid.Column="0"
MinHeight="300"
MaxHeight="300"
Visibility="{Binding Path=IsVoyageHistoryShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<local:VesselHistoryUserControl
Grid.Row="3"
Grid.Column="0"
MinHeight="300"
MaxHeight="300"
Visibility="{Binding Path=IsVesselHistoryShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<local:VoyageEvents
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
VerticalAlignment="Top"
Visibility="{Binding Path=IsVoyageEventsShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<controls2:ProgressIndicator AutomationProperties.AutomationId="showProgressForLoadingViews"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
Width="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
CircleBorder="{StaticResource ListBox.BorderBrush}"
CircleFill="{StaticResource ListBox.BorderBrush}"
IndicatorEnabled="{Binding IsDataLoading}" />
<!-- Buttons -->
<Grid Grid.Row="4" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Last Refresh:" />
<TextBlock
Margin="2,0,4,0"
VerticalAlignment="Center"
Text="{Binding LoadDate, StringFormat=G}" />
</StackPanel>
<Button AutomationProperties.AutomationId="AddNewVoyageButton"
Grid.Row="0"
Grid.Column="1"
Padding="0"
Command="{Binding AddVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Add a new voyage to this View (ALT + A)">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Add}" />
<Label Style="{StaticResource MwLabelStyle}">_Add</Label>
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="refreshVoyageButton"
Grid.Row="0"
Grid.Column="2"
Padding="0"
Command="{Binding RefreshVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Refresh the this View (modified entries are left unchanged)">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Refresh}" />
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Refresh" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="showVoyageHistroyButton"
Grid.Column="4"
Margin="2,2,2,2"
Padding="0"
VerticalAlignment="Center"
Command="{Binding ShowVoyageHistoryCommand}"
Focusable="False"
ToolTip="Show the selected voyage's change history"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource ShowVoyageHistory}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Hide Voyage History"
Visibility="{Binding IsVoyageHistoryShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Show Voyage History"
Visibility="{Binding IsVoyageHistoryShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="showVesselHistroyButton"
Grid.Column="5"
Margin="2,2,2,2"
Padding="0"
VerticalAlignment="Center"
Command="{Binding ShowVesselHistoryCommand}"
Focusable="False"
ToolTip="Show the selected vessel's voyage history"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource ShowVesselHistory}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Hide Vessel History"
Visibility="{Binding IsVesselHistoryShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Show Vessel History"
Visibility="{Binding IsVesselHistoryShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="showVoyageButton"
Grid.Column="6"
Margin="2,2,2,2"
Padding="0"
VerticalAlignment="Center"
Command="{Binding ShowVesselVisitsCommand}"
Focusable="False"
ToolTip="Show the selected voyage's events"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Anchor}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Hide Voyage Events"
Visibility="{Binding IsVoyageEventsShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Show Voyage Events"
Visibility="{Binding IsVoyageEventsShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
</StackPanel>
</Button>
<Border Grid.Row="0" Grid.Column="8">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDuplicateView, Mode=TwoWay}" Value="true">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Button AutomationProperties.AutomationId="DuplicateCheckButton"
Padding="0"
Command="{Binding DuplicateVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Switch to duplicate Voyages (ALT + D)"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Duplicate}" />
<AccessText Style="{StaticResource MwAccessTextLabelStyle}" Text="{Binding VoyageDuplicateText}" />
</StackPanel>
</Button>
</Border>
<Button AutomationProperties.AutomationId="PublishVoyagesButton"
Grid.Row="0"
Grid.Column="9"
Padding="0"
Command="{Binding PublishVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Publish any modified Voyages (ALT + P)"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Publish}" />
<AccessText Style="{StaticResource MwAccessTextLabelStyle}" Text="{Binding VoyagePublishText}" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="UndoSingleVoyageButton"
Grid.Row="0"
Grid.Column="10"
Padding="0"
Command="{Binding UndoSingleChangedVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Locally Undo unpublished changes to the selected voyage"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Undo}" />
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Undo Selected" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="UndoandUnpublishVoyageButton"
Grid.Row="0"
Grid.Column="11"
Padding="0"
Command="{Binding UndoChangedVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Locally Undo any changed and unpublished voyages"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Undo}" />
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Undo All" />
</StackPanel>
</Button>
</Grid>
</Grid>
</DataTemplate>
</dx:DXTabControl.ItemTemplate>
</dx:DXTabControl>
My FlaUIapproach of locating the Controls is below
public IMainWindow ConfirmCreatedView()
{
_logger.Info("Checking the newly created View on the screen");
//Apoorv: Need to find TabItem here
_controlAction.Highlight(ViewsTabControl); // This highlights the TabControl- Works
int NumberOfActiveTabs = ViewsTabControl.TabItems.Length; // This gives me no of TabItems
TabItem SelectedTab= ViewsTabControl.SelectedTabItem as TabItem; // Gives me Null here
var newTab = ViewsTabControl.SelectedTabItemIndex ; // Give me -1 here
_controlAction.Highlight(ViewsTabControl.TabItems[2]); // Works. It highlights the TabItem at position 2
_controlAction.ClickWait<TabItem>(ViewsTabControl.TabItems[2]); // This goes and clicks the tab item
TabItem SelectedTabs = ViewsTabControl.SelectedTabItem as TabItem;
var check = ViewsTabControl.TabItems[2].FindAllChildren();
// TabItem ti = ViewsTabControl.SelectedItem as TabItem;
//_controlAction.Highlight()
_controlAction.Highlight(CloseCurrentView); // highlights the close button atTabItem[0]
_controlAction.Click<Button>(CloseCurrentView); // closes it
return this;
}
I am using FlaUI to Find the TabControl using AutomationID as shown below
private Tab ViewsTabControl => _uiAutomation.FindElement("ViewsParentTabControl", Automation.FindBy.Id).AsTab();
private TabItem ViewsTabItem => _uiAutomation.FindElement("DXTabItem", Automation.FindBy.Id).AsTabItem();
I would like to find the curently active TabItem based on the Index and then go and click the close button by automating it.
TabItem SelectedTab= ViewsTabControl.SelectedTabItem as TabItem; // Gives me Null here
var newTab = ViewsTabControl.SelectedTabItemIndex ; // Give me -1 here
It is not TabItem it is DXTabItem. This is the type you should cast to.
DXTabItem SelectedTab = ViewsTabControl.SelectedTabItem as DXTabItem;
DevEXpress don't create automation peers for controls within ItemHeaderTemplate. It will be necessary to use a custom automation peer to provide this functionality. For example, I used the following class for test purposes:
public class DXTabItemAutomationPeerEx : DXTabItemAutomationPeer, ISelectionItemProvider {
private DXTabItem TabItem => base.Owner as DXTabItem;
private DXTabControl TabControl => TabItem.With((DXTabItem x) => x.Owner);
public DXTabItemAutomationPeerEx(DXTabItem ownerCore) : base(ownerCore) { }
protected override List<AutomationPeer> GetChildrenCore() {
List<AutomationPeer> children = base.GetChildrenCore();
foreach (var button in LayoutTreeHelper.GetVisualChildren(Owner).OfType<Button>())
children.Add(new ButtonAutomationPeer(button));
return children;
}
bool ISelectionItemProvider.IsSelected { get {
if (TabControl != null) {
return TabControl.SelectedContainer == TabItem;
}
return false;
}
}
}
Post adding this code inside my MainPage.Xaml.cs , I added a static constructor to register it
static MainWindow() {
NavigationAutomationPeersCreator.Default.RegisterObject(typeof(DXTabItem), typeof(DXTabItemAutomationPeerEx), owner => new DXTabItemAutomationPeerEx((DXTabItem)owner));
}
post this , these lines work as charm
TabItem CurrentTab = ViewsTabControl.SelectedTabItem as TabItem;
var Children = ViewsTabControl.FindAllChildren();
foreach (var child in Children) {
var subChildren = child.FindAllChildren();
}
I am trying to show the overall progress of current playing song in below format.
hh:mm:ss / hh:mm:ss ---> current time in hh:mm:ss / total time in hh:mm:ss
<Border Margin="30,0,20,0" Name="NowPlayingScurbberPanel" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" RelativePanel.Below="NowPlayingButtonPanel" RelativePanel.AlignBottomWithPanel="True">
<StackPanel Visibility="{Binding Path=ShouldProgressBarBeVisible, Converter={StaticResource BoolToVisibilityConverter}}" MinHeight="40">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Uid="NowPlayingCurrentMediaTimeText" Margin="0,0,80,30" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" Text="{Binding Path=DisplayedMediaTimeCurrent}" HorizontalAlignment="Right" />
<TextBlock x:Uid="slash" Margin="0,0,60,30" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" Text=" / " HorizontalAlignment="Right" />
<Slider x:Uid="NowPlayingScrubber" Margin="0,20,0,0" Style="{StaticResource NowPlayingMediaScrubberStyle}" Grid.Column="1" x:Name="NowPlayingScrubber" Value="{Binding Path=ProgressBarPercentage, Mode=TwoWay}" DragStarting="OnScrubberDragStarted" DropCompleted="OnScrubberDragCompleted" ValueChanged="OnScrubberDragDelta" IsEnabled="{Binding Path=ScrubberEnabled}" />
<TextBlock x:Uid="NowPlayingTotalMediaTimeText" Margin="60,0,0,30" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" Text="{Binding Path=DisplayedMediaTimeTotal}" HorizontalAlignment="Right" />
</Grid>
</StackPanel>
</Border>
Things are working fine if total and current played time in less than an hour but when it cross more than a hour than "Slash" overlap with total time. If i give additional margin then content with less than an hour time looks bad.
How can i give margin based on content length or is there any better solution to solve this problem.
Thanks
You just need to tweak your layout slightly. Depends how you want it to look exactly, do you want it to overlay or be at the side of the slider?
Something like this will put the timers first and then the progress bar but you should be able to tweak to how you wish.
<Border Margin="30,0,20,0" Name="NowPlayingScurbberPanel" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" RelativePanel.Below="NowPlayingButtonPanel" RelativePanel.AlignBottomWithPanel="True">
<StackPanel Visibility="{Binding Path=ShouldProgressBarBeVisible, Converter={StaticResource BoolToVisibilityConverter}}" MinHeight="40">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Uid="NowPlayingCurrentMediaTimeText" Margin="5" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" Text="{Binding Path=DisplayedMediaTimeCurrent}" HorizontalAlignment="Right" Grid.Column="0" />
<TextBlock x:Uid="slash" Margin="5" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" Text=" / " HorizontalAlignment="Right" Grid.Column="1" />
<TextBlock x:Uid="NowPlayingTotalMediaTimeText" Margin="5" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" Text="{Binding Path=DisplayedMediaTimeTotal}" HorizontalAlignment="Right" Grid.Column="2" />
<Slider x:Uid="NowPlayingScrubber" Margin="5" Style="{StaticResource NowPlayingMediaScrubberStyle}" x:Name="NowPlayingScrubber" Value="{Binding Path=ProgressBarPercentage, Mode=TwoWay}" DragStarting="OnScrubberDragStarted" DropCompleted="OnScrubberDragCompleted" ValueChanged="OnScrubberDragDelta" IsEnabled="{Binding Path=ScrubberEnabled}" Grid.Column="3" />
</Grid>
</StackPanel>
</Border>
This could be further simplified by using a single TextBlock with a Run E.G.
<TextBlock x:Uid="NowPlayingCurrentMediaTimeText" Margin="5" Style="{StaticResource NowPlayingMediaTimeStyle}" Grid.Row="0" HorizontalAlignment="Right" Grid.Column="0" >
<Run Text="{Binding Path=DisplayedMediaTimeCurrent}"/>
<Run Text=" \ "/>
<Run Text="{Binding Path=DisplayedMediaTimeTotal}"/>
</TextBlock>
You would probably need a Value Converter to get the margin exactly how you want it.
<StackPanel Orientation="Horizontal">
<TextBox x:Name="aTextBox" Width="100" Height="30" />
<TextBlock x:Name="aTextBlock" Width="100" Height="30" Text="some text"
Margin="{Binding ElementName=aTextBox, Path=Text.Length, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
You can do this in the code behind.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void aTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
aTextBlock.Margin = new Thickness(10 + aTextBox.Text.Length * 2, 0, 0, 0);
aTextBlock.Text = aTextBox.Text;
aTextBox.Width = 100 + aTextBox.Text.Length * 2;
aTextBlock.Width = 100 + aTextBox.Text.Length * 2;
}
}
<StackPanel Orientation="Horizontal">
<TextBox x:Name="aTextBox" Width="100" Height="30" TextChanged="aTextBox_TextChanged" />
<TextBlock x:Name="aTextBlock" Width="100" Height="30" Text="some text" />
</StackPanel>
I have a the Following FlipView in a winRT project
<FlipView x:Name="Flip" GotFocus="FlipView_GotFocus" Grid.Row="1" ItemsSource="{Binding Controls, ElementName=pageRoot}" SelectedItem="{Binding SelectedControl, ElementName=pageRoot, Mode=TwoWay}">
<FlipView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter Content="{Binding}" />
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
inside of it i will have several usercontrols that have some TextBox, but when i focus in one of the TextBox , the virtual Keyboard gets in front of the other TextBox, it doesnt "lift" the app like it normally does when i have a simple page with TextBoxs.
Is there a way to detect Keyboard showing up and pulling the view of the app up?
Here is one of the UserControl im using
<UserControl.Resources>
<ResourceDictionary>
<common:ByteArrayToBitmapImageConverter x:Key="ByteArrayToBitmapImageConverter" />
<common:StringToValidityConverter x:Key="StringToValidityConverter" />
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<StackPanel Style="{StaticResource SubHeaderStyle}">
<Image Source="/Images/Contract/Sales.png" Style="{StaticResource SubHeaderImageStyle}" />
<TextBlock x:Uid="Sale" Style="{StaticResource SubHeaderTextStyle}" />
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Grid.RowSpan="6" Width="300" Source="{Binding Picture, Converter={StaticResource ByteArrayToBitmapImageConverter}}" />
<TextBlock x:Uid="SalesOffice" Grid.Row="1" Grid.Column="2" />
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding Office, Mode=TwoWay}" Style="{StaticResource TextBoxStyle}"
common:TextBoxBehavior.Validity="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource StringToValidityConverter}}" />
<TextBlock x:Uid="SalesAgent" Grid.Row="2" Grid.Column="2" />
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding AgentName, Mode=TwoWay}" Style="{StaticResource TextBoxStyle}"
common:TextBoxBehavior.Validity="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource StringToValidityConverter}}" />
<TextBlock x:Uid="MobilePhone" Grid.Row="3" Grid.Column="2" />
<TextBox Grid.Row="3" Grid.Column="3" Text="{Binding MobilePhone, Mode=TwoWay}" Style="{StaticResource TextBoxStyle}"
common:TextBoxBehavior.Validity="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource StringToValidityConverter}}" InputScope="Number" />
<TextBlock x:Uid="EmailAddress" Grid.Row="4" Grid.Column="2" />
<TextBox Grid.Row="4" Grid.Column="3" Text="{Binding EmailAddress, Mode=TwoWay}" Style="{StaticResource TextBoxStyle}"
common:TextBoxBehavior.Validity="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource StringToValidityConverter}}" />
</Grid>
</StackPanel>
and here is how it looks
Edit:
seems that i can detect the keyboard with
Windows.UI.ViewManagement.InputPane.GetForCurrentView().Showing
Windows.UI.ViewManagement.InputPane.GetForCurrentView().Hidding
now i just need to learn how to pull my view up.
As you found, you can use the InputPane's Showing and Hiding events to detect the InputPane's visibility changes. The InputPaneVisibilityEventArgs includes the OccludedRect that it will cover, and you can apply a RenderTransform to your page to Translate it out of the way.
<Page.RenderTransform>
<CompositeTransform x:Name="pageTransform"/>
</Page.RenderTransform>
And a painfully naive implementation:
void Page_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
// We probably want something more sophisticated to make sure the
// focus control and any dependencies are in view
pageTransform.TranslateY -= args.OccludedRect.Height;
// Tell the InputPane we already handled things so it doesn't move the page again
args.EnsuredFocusedElementInView = true;
}
void Page_Hiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
pageTransform.TranslateY = 0;
args.EnsuredFocusedElementInView = true;
}
In reality you'll want to do the math to make sure the necessary controls are in view. You can use animations to make the shift more smooth. If you want to get even more creative you can switch to a new visual state which has just the necessary fields for editing in a more friendly layout. In your UserControl case you may want to shift just the control rather than the page.
Also give it a test on a Windows 10 desktop since the soft-keyboard behavior will interact a bit differently with a windowed app.
Firstly, thank you for taking the time out to read this post. All contributions are very much appreciated.
I'm having difficulty understanding how I can bind a ComboBox ItemsSource within a DataTemplate to an ObservableCollection.
Here's my code thus far:
DataTemplate Template (notice the combo's at the bottom of the template):
<DataTemplate x:Key="ListBoxCustomTemplate">
<Grid Margin="4" HorizontalAlignment="Stretch" x:Name="lstBoxItemRoomGrid" >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontWeight="Bold" Text="{Binding TemplateGroupName}" />
<Image x:Name="imgDeleteListBoxItem" Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Source="/Icons/Print-Groups-Config/delete-32.png" Height="25" Cursor="Hand"
ToolTip="Remove template" VerticalAlignment="Center"
HorizontalAlignment="Right" MouseLeftButtonUp="imgDeleteListBoxItem_MouseLeftButtonUp">
<Image.Style>
<Style>
<Setter Property="Image.Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=lstBoxItemRoomGrid}" Value="True">
<Setter Property="Image.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding TemplateDescription}" TextWrapping="WrapWithOverflow" />
<!-- Header Template Selection -->
<Label Grid.Row="2" Grid.Column="0" Margin="0,3,0,0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Content="Select Header:" FontWeight="DemiBold" Foreground="DarkGray" />
<telerik:RadComboBox x:Name="radComboHeaderTemplate" Grid.Row="3" Grid.Column="0" Width="120" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"
ClearSelectionButtonVisibility="Visible" SelectedValue="{Binding TemplateHeaderID}" />
<!-- Footer Template Selection -->
<Label Grid.Row="2" Grid.Column="1" Margin="0,3,0,0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Content="Select Footer:" FontWeight="DemiBold" Foreground="DarkGray" />
<telerik:RadComboBox x:Name="radComboFooterTemplate" Grid.Row="3" Grid.Column="1" Width="120" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"
ClearSelectionButtonVisibility="Visible" SelectedValue="{Binding TemplateFooterID}" />
</Grid>
</DataTemplate>
When my Window loads, I download the collection data from my database and store into a local collection. Note that there are two Collections, one for each of the 2 ComboBoxes in my DataTemplate.
//Header Templates
private ObservableCollection<TemplateHeaderFooter> templatesHeader = new ObservableCollection<TemplateHeaderFooter>();
//Footer Templates
private ObservableCollection<TemplateHeaderFooter> templatesFooters = new ObservableCollection<TemplateHeaderFooter>();
//--- Constructors ---
public PrintTemplateGroupsConfigWindow()
{
InitializeComponent();
//Download Data From DB
this.templatesHeader = TemplateHeaderFootersDB.GetAllTemplatesOfType(1);
this.templatesFooters = TemplateHeaderFootersDB.GetAllTemplatesOfType(2);
}
How do I get the collection Data templatesFooters & templatesHeader into the the ItemsSources of their respective ComboBoxes?
The datatemplate is for a ListBox.
<telerik:RadListBox x:Name="lstBoxPrintGroupTemplates" Height="300" Width="280" ItemsSource="{Binding}" IsEnabled="False"
ItemTemplate="{StaticResource ListBoxCustomTemplate}" Style="{StaticResource DraggableListBox}" >
Many thanks. Any help is appreciated.
Define properties wrappers over the variables of your collections and then you can bind them to comboboxes as:
ItemsSource="{Binding TemplatesHeader, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
public ObservableCollection<TemplateHeaderFooter> TemplatesHeader
{
get{return templatesHeader;}
}
Similarly you can do for other property
I have a ComboBox that has an ItemTemplate with a CheckBox in it (read Dropdown CheckBoxList). I basically want to have a separate binding for the text in the combobox (both when an item is selected, and if an item isn't selected). I've tried a few different methods but either can't seem to get them to work with my setup, or can't find they have some issues. I've even tried a few mixes and matches of them. Usually I find they either don't work when an item isn't specifically selected (which could be possible if the user checks a few boxes then clicks out of the ComboBox), or aren't updating the text properly.
My xaml is this (the items of focus are the DataTemplates with the ComboBoxes in them):
<UserControl x:Class="BestClient.ucReportViewer"
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:BestClient"
mc:Ignorable="d"
d:DesignHeight="315" d:DesignWidth="388" Background="#FFD7DFEC">
<UserControl.Resources>
<DataTemplate x:Key="datetime">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<DatePicker Tag="{Binding rfParameter}" SelectedDate="{Binding rfValues, Mode=TwoWay}" Width="200" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="office">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<ComboBox x:Name="officeComboBox" Tag="{Binding rfParameter}" Width="200" ItemsSource="{Binding Path=DataContext.OfficeList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay}" VerticalAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Tag="{Binding id}" IsChecked="{Binding isSelected}" Width="200" Content="{Binding value}" Margin="2" x:Name="CheckBox" Checked="OfficeCheckBox_Checked"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="carrier">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<ComboBox Tag="{Binding rfParameter}" Width="200" ItemsSource="{Binding Path=DataContext.CarrierList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay}" VerticalAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Tag="{Binding id}" IsChecked="{Binding isSelected}" Width="200" Content="{Binding value}" Margin="2"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="defaultTemplate">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="{Binding rfName}" Width="100" VerticalAlignment="Center" />
<TextBox Tag="{Binding rfParameter}" Width="200" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
<local:ReportFilterTemplateSelector x:Key="ReportFilterTemplateSelector" />
</UserControl.Resources>
<Grid x:Name="ReportViewer">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="45"/>
<RowDefinition Height="*"/>
<RowDefinition Height="45"/>
</Grid.RowDefinitions>
<Viewbox Grid.Row="0" Grid.Column="0">
<TextBlock Margin="10" TextWrapping="Wrap" Text="Select a Report:"/>
</Viewbox>
<ComboBox Grid.Column="1" Margin="10" Grid.ColumnSpan="2" ItemsSource="{Binding ReportList}" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedItem="{Binding SelectedReport}" VerticalContentAlignment="Center" />
<ListView x:Name="FilterList" Margin="10,0" Grid.Row="1" Grid.ColumnSpan="3" ItemTemplateSelector="{StaticResource ReportFilterTemplateSelector}" ItemsSource="{Binding reportFilters, Mode=TwoWay}" />
<Button Command="{Binding OpenReport}" Content="Open Report" Grid.Column="2" Margin="10" Grid.Row="2" VerticalAlignment="Stretch"/>
</Grid>
</UserControl>
Ideally, I'd like to bind the display text of the combobox with the OfficeListValues method in my ViewModel.
{Binding Path=DataContext.OfficeListValues, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}
Any help would be appreciated!