I am trying to change the title of a panel in silverlight depending on what the user clicks. What I have for the panel controls is
<Silverlight_Controls:FloatingPanel
x:Name="pnlEntities"
Margin="0,0,0,20"
VerticalAlignment="Bottom"
HorizontalAlignment="left"
Width="auto"
Height="200"
Title=""
TitleColor="White"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
WindowBackgroundBorder="DarkGray"
WindowBackground="DodgerBlue"
ContentBackgroundBorder="Transparent"
ContentBackground="WhiteSmoke"
IsCloseButtonVisible="True"
IsDraggable="True"
IsHeightResizeable="True"
IsWidthResizeable="True"
IsHeaderVisible="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<Data:DataGrid
</Data:DataGrid>
I have the button that I confirm does fire off but it doesn't change anything. I think I am not understanding if something needs to be reloaded or if updatelayout is the wrong thing to call.
private void buttInformation_ExecuteCompleted(object sender, IdentifyEventArgs e)
{
pnlEntities.Title = "AreaA";
pnlEntities.UpdateLayout();
}
Looks like you might be using a custom control. Find the control that is displaying the text in the title and change the text value of that control.
Related
I am using MVVM for my application and have a form that allows the user to enter basic personnel information. The form includes a UserControl which is, basically, an ItemsControl that includes textBoxes that can be dynamically created. This is a simplified version:
<ItemsControl x:Name="items" ItemsSource="{Binding MyItemsCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="row">
<TextBox x:Name="textBox" Text="{Binding ContactInfo, ValidatesOnExceptions=True}" extensions:FocusExtension.IsFocused="{Binding IsFocused}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button x:Name="NewItemButton" Command="{Binding AddItemToMyCollectionCommand}" />
I want the TextBox that has just been created to receive focus, therefore I added an attached property. This is part of it:
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusExtension), new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
{
uie.Focus();
}
}
In the form that contains the UserControl there are several other text boxes before and after. The UserControl has its own ViewModel, which I set as the DataContext of the control through a property in the container's ViewModel. Basically, a simplified version of the container looks like this:
<StackPanel Orientation="Horizontal" />
<TextBox x:Name="firstName" />
<TextBox x:Name="lastName" />
<local:DynamicFormUserControl
x:Name="phones"
DataContext="{Binding PhonesViewModel}" />
<local:DynamicFormUserControl
x:Name="emails"
DataContext="{Binding EmailsViewModel}" />
<TextBox x:Name="address" />
</StackPanel>
My problem is that I want the firstName TextBox to get the focus when the form is loaded for the first time, but the form keeps on placing the focus on the first TextBox of the phones UserControl. I tried to override it by using firstName.Focus() on the Loaded event of the form, but this didn't work, and no matter what I tried the focus is still on the phones userControl instead of the first element in the form that contains it.
Does anybody have any idea how to solve this?
Thanks.
Here you go
add FocusManager.FocusedElement="{Binding ElementName=firstName}" to your stack panel
<StackPanel Orientation="Horizontal"
FocusManager.FocusedElement="{Binding ElementName=firstName}"/>
<TextBox x:Name="firstName" />
<TextBox x:Name="lastName" />
<local:DynamicFormUserControl
x:Name="phones"
DataContext="{Binding PhonesViewModel}" />
<local:DynamicFormUserControl
x:Name="emails"
DataContext="{Binding EmailsViewModel}" />
<TextBox x:Name="address" />
</StackPanel>
also notice that you may need to prevent items control in the user control from focusing itself
<ItemsControl x:Name="items" Focusable="False" >
<ItemsControl.ItemTemplate>
I guess I managed to find a solution. The problem was that the form I created was itself a user control inside a window, and never got focus. I didn't think that would be relevant so I didn't mention it in my previous post- sorry. I found in this solution for forcing focus to a user control.
Basically, when I have a UserControl inside a window it doesn't get focus even if I try to set the focus with either Focus() or FocusedElement. So to overcome this problem I found on a different post a workaround. Basically I added it to the code-behind of the UserControl that contains the firstName TextBox. If we call the UserControl, say, PersonalInfoUserControl, the constructor of the control would look like this:
public PersonalInfoUserControl()
{
InitializeComponent();
this.IsVisibleChanged += new DependencyPropertyChangedEventHandler(UserControl_IsVisibleChanged);
}
I added an event handler to the IsVisibleChanged event of the control. The method would look like this:
void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue == true)
{
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate()
{
firstName.Focus();
}));
}
}
Recently I had been looking for a way to make the tabs in a TabControl editable and came across This example on telerik's website. That did exactly what I wanted but it got me thinking about a similar usage for buttons. I was wondering if it would be possible to use something like that and make a button that would show a textbox instead of the content presenter when say, you right click the button? I tried to make something like this work but so far have only ended up with a blank button.
<Button x:Name="SB" Height="222" Width="222" Click="SB_Click">
<ContentControl.ContentTemplate>
<DataTemplate>
<local:SuperButton Content="{Binding Path=x, Mode=TwoWay}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</Button>
Where x is a string variable and using the code behind from the link above (with a class name change, of course).
edit: This button will be in an itemscontrol, so I don't think naming the inner elements in xaml will work, but I do like the ease of Wolfgang's answer.
The WPF Content Model is really flexible and allows literally anything inside anything.
This is perfectly valid XAML:
<Button>
<TextBox/>
</Button>
Or even:
<Button>
<MediaElement Source="C:\Videos\WildLife.wmv"/>
</Button>
You can simply host a (e.g.) label (TextBlock) with the text AND a TextBox inside the Button and set their Visiblity properties.
That way, if you right click the button, the TextBox shows up.
<Button>
<Grid>
<TextBox Text=normal button caption" x:Name="label" />
<TextBox
x:Name="textbox"
Text="visible on right click"
MouseRightButtonDown="HandleRightClick"/>
</Grid>
</Button>
And then in your C# code create an event handler to set the Visiblity correctly.
void HandleRightClick(object sender, MouseButtonEventArgs e)
{
label.Visibility = Visibility.Collapsed;
textBlock.Visibility = Visibility.Visible;
}
Hopefully this is an easy question. I'm using the ListBoxDragDropTarget from the Silverlight Toolkit to set up drag and drop from one ListBox to another. I can't seem to get the event to fire. Here's my XAML code:
<toolkit:ListBoxDragDropTarget HorizontalAlignment="Left"
HorizontalContentAlignment="Stretch"
VerticalAlignment="Top"
VerticalContentAlignment="Stretch"
Margin="39,117,0,0"
Grid.Row="1"
AllowDrop='True'>
<ListBox x:Name='columnHeadings'
MinHeight='100'
MinWidth='100'>
</ListBox>
</toolkit:ListBoxDragDropTarget>
<toolkit:ListBoxDragDropTarget AllowDrop='True'
Grid.Column='1'
Grid.Row='1'
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
VerticalAlignment="Center"
HorizontalAlignment="Left">
<ListBox x:Name='customerFields'
Grid.Column='1'
Grid.Row='1'
Visibility='Collapsed'
Drop='CustomerFieldsDrop'>
</ListBox>
</toolkit:ListBoxDragDropTarget>
And here's my event handler in the code behind page:
private void CustomerFieldsDrop(object sender, DragEventArgs e)
{
MessageBox.Show(string.Format("Something was dropped!"));
}
As you can see, I was aiming for something real simple. I tried assigning an event handler to the parent ListBoxDragDropTarget for the customerFields List Box; ironically, that worked.
My purpose here is to allow a user to import a text file and get a listing of the file's column headers in one List Box and then "connect" them to data fields listed in the second List Box. So no list reordering or moving items from one list to another.
The columnHeadings.ItemsSource property is a string[] object. The customerFields.ItemsSource property is an IEnumerable<string> object.
Any insight would be appreciated.
I think the AllowDrop="True" and Drop="EventName" properties need to be within the same element to work. You probably have to set the AllowDrop property to "True" in the ListBox itself:
<ListBox x:Name="customerFields"
Grid.Column="1"
Grid.Row="1"
Visibility="Collapsed"
Drop="CustomerFieldsDrop"
AllowDrop="True"
</ListBox>
Or add the Drop="CustomerFieldsDrop" property to the ListBoxDragDropTarget tag:
<toolkit:ListBoxDragDropTarget AllowDrop='True'
Grid.Column='1'
Grid.Row='1'
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Drop="CustomerFieldsDrop">
Either one should work...
I am trying to create UI from XAML at runtime, with something like
private void Application_Startup (object esender, StartupEventArgs e)
{
this.RootVisual = (UIElement)(XmlReader.Load(e.InitParams["Xaml"])
If I feed it this XAML:
<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sdk="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls">
<StackPanel>
<TextBox Width="120" Margin="8" Text="Edit Me" />
<CheckBox Margin="8">Normal</CheckBox>
<ComboBox Margin="8" Width="120" SelectedIndex="1">
<ComboBoxItem Content="First Normal Item" />
<ComboBoxItem Content="Second Normal Item" />
</ComboBox>
</StackPanel>
</Canvas>
then the check box and list behave as expected, but my TextBox does not respond to typing, it stays with its initial value.
The really weird (to me) part is that if I put a handler for KeyDown on to the RootVisual, and in there display a message box, it works. If I have an empty handler or no handler it doesn't.
Do I need to set up some explicit handling for some events? If so, which ones, and how do I handle them?
Upadate: as suggested, I tried putting the dynamic markup into the MainPage of a new app, like this:
public MainPage()
{
InitializeComponent();
var dynamic = XamlReader.Load(xaml);
this.LayoutRoot.Children.Add(dynamic as UIElement);
}
where xaml is a string literal containing the content as above, and everything else is just how VS2010 wizard left it. That works. But I can't see what the effective difference is.
Update update: that's a red herring; the difference is the environment. It works in VS, but not in the Silverlight ActiveX control that I am using in the real app.
Did you define the root namespace on your root element?
<param name="initParams" value="xaml=<TextBox xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' Text='hi'/>" />
Just a shot in the dark here, but have you tried adding the dynamically created content as the child of a static "MainPage.xaml" Grid instead of as RootVisual?
Check for IsEnabled="True" property in your main XAML file, if it is set to false then controls will not be editable.
how can I access the arrow buttons on the ends of scrollbars in silverlight? Are they button controls which can be accessesed through thescrollbar class or something else?
The reason I need to know this is so that when someone click on either of the arrow buttons I can run some custom functionality to the scrollbar
If you need to know what button of the scrollbar was clicked you can could access that via the ValueChanged property of the ScrollBar
For instance I've got a simple scroll bar with a textblock and on each click, the textblock displays which button was clicked.
<Grid x:Name="LayoutRoot" Background="White">
<ScrollBar Height="200" Orientation="Vertical" Width="20" ValueChanged="ScrollBar_ValueChanged" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="150,21,0,0" Name="textBlock1" Text="" Width="100" VerticalAlignment="Top" />
</Grid>
and the code behind would be
private void ScrollBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (e.NewValue > e.OldValue)
textBlock1.Text = "Down Arrow Clicked";
else
textBlock1.Text = "Up Arrow Clicked";
}
Solved this problem like so:
foreach( var o in horizontalBar.GetVisualDescendants( ) )
{
if(o is RepeatButton)
{
//set call back based on the name of the repeatbutton
}
}