i try to bind the TextBox's text in MenuItem's header to MenuItem's Tag property.
but it won't work correct, always get Null in Tag property.
the code is like below...
<Button x:Name="Button1" Content="Test" HorizontalAlignment="Left" Width="182" Height="34" VerticalAlignment="Top" Margin="160,113,0,0">
<Button.ContextMenu>
<ContextMenu PlacementTarget="{Binding ElementName=Button1}" Placement="Bottom">
<MenuItem Tag="{Binding ElementName=TextBox1, Path=Text}" Click="MessageBox_ShowTag">
<MenuItem.Header>
<Grid Height="25" MinWidth="153">
<Label Content="Label1" Width="86" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
<TextBox x:Name="TextBox1" VerticalContentAlignment="Center" Margin="91,0,0,0"/>
</Grid>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
When click on menuitem, call the MessageBox to show the tag in MenuItem
( MessageBox.Show( ( sender as MenuItem ).Tag?.ToString() ); )
MessageBox has show but content is always empty.
Result:
how can i bind to textbox?
I don't know why you have to bind it like that. An alternative would be to bind to a property (here: MyText) that implements INotifyPropertyChanged, and then pass the DataContext to the menu like this:
<Button x:Name="Button1" Content="Test" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Button.ContextMenu>
<ContextMenu Placement="Bottom" DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem>
<MenuItem.Header>
<Grid Height="25" MinWidth="153">
<Label Content="Label1" Width="86" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
<TextBox Name="TextBox1" Text="{Binding Path=MyText}"
VerticalContentAlignment="Center" Margin="91,0,0,0"/>
</Grid>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
And then not relay on Click event to get the TextBox value at all.
If you want to know why your binding doesn't work, its because your MenuItem can't find an object named TextBox1 in its Namescope. If you must (namescopes are a bit tricky), you may make it work by creating a new Namescope for your MenuItem and registering the name for the TextBox:
NameScope.SetNameScope(mi1, new NameScope());
mi1.RegisterName("TextBox1", TextBox1);
where mi1 is the name of your MenuItem, then your binding will work:
<Button x:Name="Button1" Content="Test" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Button.ContextMenu>
<ContextMenu Placement="Bottom">
<MenuItem Tag="{Binding ElementName=TextBox1, Path=Text}" Click="MessageBox_ShowTag" Name="mi1">
<MenuItem.Header>
<Grid Height="25" MinWidth="153">
<Label Content="Label1" Width="86" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
<TextBox Name="TextBox1" VerticalContentAlignment="Center" Margin="91,0,0,0"/>
</Grid>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
Also, avoid x:Name whenever you can. It can cause some nasty memory leaks. Use Name instead.
Like mentioned in the comment also, there could be better solution to actual problem you are trying to solve.
But anyhow if you want solution for your specific problem it can be solved by using x:Reference in place of ElementName like this:
<MenuItem Tag="{Binding Source={x:Reference TextBox1}, Path=Text}"/>
ElementName is not working because VisualTree is different. In case interested read further here - ElementName v/s x:Reference.
Try binding via RelativeSource:
<TextBox x:Name="TextBox1" Text="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType={x:Type MenuItem}}}" VerticalContentAlignment="Center" Margin="91,0,0,0"/>
Related
I tried using a textbox inside a WPF Material Design transitioner slide. The textbox is visible even when changing slides.
A dotted line from the textbox on the next slide is visible, and viceversa.
Has anyone else encountered this issue? Is there any workaround I could use?
This is the xaml I used. I am using the transitioner control although I believe the flipper control causes a similar effect when used with textboxes.
<Grid>
<materialDesign:Transitioner SelectedIndex="0">
<materialDesign:TransitionerSlide>
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="Hello, this is my first page!" Margin="10"/>
<TextBox materialDesign:HintAssist.Hint="Type your first text here!" Margin="10"/>
<Button Command="{x:Static materialDesign:Transitioner.MoveNextCommand}" Content=">" HorizontalAlignment="Center" Margin="10"/>
</StackPanel>
</materialDesign:TransitionerSlide>
<materialDesign:TransitionerSlide>
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="Hello, this is my 2nd page!" Margin="15"/>
<TextBox materialDesign:HintAssist.Hint="Type your second text here!" Margin="15"/>
<Button Command="{x:Static materialDesign:Transitioner.MovePreviousCommand}" Content="<" HorizontalAlignment="Center" Margin="15"/>
</StackPanel>
</materialDesign:TransitionerSlide>
</materialDesign:Transitioner>
</Grid>
I believe the issue might lie in the dotted line that appears when a textbox is disabled, so possibly by removing that, the textbox would no longer show through slides. But that's just my guess.
Any help is appreciated!
For the best approach, please refer to this answer.
Try to add the following implicit style to your App.xaml or window:
<Style TargetType="materialDesign:BottomDashedLineAdorner">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
I try several ways and I found solution
please set BorderThickness="0" in textboxes like this
<TextBox materialDesign:HintAssist.Hint="Type your second text here!" Margin="10" BorderThickness="0"/>
Wrapping the offending control in:
<AdornerDecorator>
</AdornerDecorator>
seems to work.
Hi problem is in your margin , please set all your margins to 10 like this
<Grid>
<materialDesign:Transitioner SelectedIndex="0">
<materialDesign:TransitionerSlide>
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="Hello, this is my first page!" Margin="10"/>
<TextBox materialDesign:HintAssist.Hint="Type your first text here!" Margin="10"/>
<Button Command="{x:Static materialDesign:Transitioner.MoveNextCommand}" Content=">" HorizontalAlignment="Center" Margin="10"/>
</StackPanel>
</materialDesign:TransitionerSlide>
<materialDesign:TransitionerSlide>
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="Hello, this is my 2nd page!" Margin="10"/>
<TextBox materialDesign:HintAssist.Hint="Type your second text here!" Margin="10"/>
<Button Command="{x:Static materialDesign:Transitioner.MovePreviousCommand}" Content="<" HorizontalAlignment="Center" Margin="15"/>
</StackPanel>
</materialDesign:TransitionerSlide>
</materialDesign:Transitioner>
</Grid>
I hope it help you
I want to write the event for list box from View Model. I try like this:-
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" Padding="5" BorderThickness="1">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="Wheat" BorderThickness="1">
<Image Name="ListPersonImage" Source="{Binding PersonImage}" Height="100" Width="100" Stretch="Uniform" Margin="10,0,0,0"/>
</Border>
<TextBlock Text="{Binding FirstName}" Name="firstName" Width="200" Foreground="White" Margin="10,10,0,0" FontWeight="SemiBold" FontSize="22" />
<Button DataContext="{Binding DataContext, ElementName=listBox1}" Command="{Binding addPerson}" Height="80" Width="80" >
<Button.Background>
<ImageBrush ImageSource="{Binding imagePath, Converter={StaticResource pathToImageConverter}}" Stretch="Fill" />
</Button.Background>
</Button>
</StackPanel>
</Border>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding ItemSelectedCommand,Mode=OneWay}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My ViewModel:-
public RelayCommand<MVVMListBoxModel> ItemSelectedCommand { get; private set; }
public MVVMListBoxViewModel()
{
ItemSelectedCommand = new RelayCommand<MVVMListBoxModel>(ItemSelected);
}
private void ItemSelected(MVVMListBoxModel myItem)
{
MessageBox.Show("Name==>" + myItem.FirstName);
//throw new NotImplementedException();
}
But nothing happening. Please let me know where I did mistake.
Thanks in advance.
Check output window to see if you got binding error. It seems that you got one, because you have ItemSelectedCommand defined in MVVMListBoxViewModel but ListBoxItem's DataContext is corresponding MVVMListBoxModel, so binding engine couldn't find the command.
Try to move definition of ItemSelectedCommand to MVVMListBoxModel and see if message box get displayed this way.
Do you want the trigger to be upon the SelectionChanged of the Listbox Item? Then the trigger should be outside the <ListBox.ItemTemplate> ... </ListBox.ItemTemplate>.
And the trigger should bind the CommandParamter to the SelectedItem
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding ItemSelectedCommand,Mode=OneWay}" CommandParameter="{Binding SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Can someone give me an example of how to style a button with XAML hat has three states (hover, normal, pressed). i want the whole area of the button to be covered with an image (one for each of the three different states) and i want text to be on top that also has three different colors for the different states. i have something like this already (without the color states on the textblock). the problem i'm having at this point is that the textblock is blocking the input events for the button undernearth (i also haven't implemented the color changes for the textblock....
current code:
<DataTemplate x:Name="SubjectItemTemplate">
<Canvas Width="225" Height="225">
<Button Canvas.Left="0" Canvas.Top="0"
Command="{Binding ElementName=LayoutRoot, Path=DataContext.NavigateToUnitsPage}"
CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate>
<Grid Background="{Binding LightThemeColor}" Width="205" Height="205">
<controls:ImageButton HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0"
NormalStateImageSource="{Binding ImageUriNormal}"
HoverStateImageSource="{Binding ImageUriHover}"
PressedStateImageSource="{Binding ImageUriPressed}" Command="{Binding ElementName=LayoutRoot, Path=DataContext.NavigateToUnitsPage}"
CommandParameter="{Binding}"/>
<TextBlock Text="{Binding Name}" FontSize="18" TextWrapping="Wrap" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,168,0,0" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Canvas>
</DataTemplate>
The reason that the ImageButton events are not being handled as expected with the TextBlock is because the TextBlock is located in-line with the ImageButton and not contained inside the ImageButton. To change this, the TextBlock has to be placed inside the ImageButton.
<controls:ImageButton HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0"
NormalStateImageSource="{Binding ImageUriNormal}"
HoverStateImageSource="{Binding ImageUriHover}"
PressedStateImageSource="{Binding ImageUriPressed}" Command="{Binding ElementName=LayoutRoot, Path=DataContext.NavigateToUnitsPage}" CommandParameter="{Binding}" >
<TextBlock Text="{Binding Name}" FontSize="18" TextWrapping="Wrap" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,168,0,0" />
</controls:ImageButton>
I tried to implement a simple Menu with wpf for the surface 2.0/pixelsense.
<s:SurfaceWindow x:Class="MenuTrial.SurfaceWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
xmlns:MenuTrial="clr-namespace:MenuTrial"
xmlns:Properties="clr-namespace:MenuTrial.Properties"
Title="MenuTrial"
>
<Grid Name="MenuGrid" Height="102" VerticalAlignment="Bottom">
<s:ScatterView HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<s:ScatterView.Resources>
<Image x:Shared="false" x:Key="IconPhoto" Source="Resources\Icons\photo.png"/>
<Image x:Shared="false" x:Key="IconCopy" Source="Resources\Icons\copy.png"/>
</s:ScatterView.Resources>
<s:ScatterViewItem Height="139"
Width="224"
Orientation="-23"
Background="#FF787878">
<s:ElementMenu
Name="MainMenu"
ActivationMode="AlwaysActive"
ActivationHost="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type s:ScatterViewItem}}}"
>
<s:ElementMenuItem Header="Menu1"/>
<s:ElementMenuItem Header="Menu2"/>
<s:ElementMenuItem Header="{x:Static Resources:Resources.IconPhoto}" Icon="{StaticResource IconPhoto}">
<s:ElementMenuItem Header="{x:Static Resources:Resources.Copy}" Icon="{StaticResource IconCopy}" Command="{x:Static MenuTrial:SurfaceWindow1.ShowMessageCommand}" CommandParameter="{Binding Path=Header, RelativeSource={x:Static RelativeSource.Self}}"/>
<s:ElementMenuItem Header="Menu 3.2" />
<s:ElementMenuItem Header="Menu 3.3"/>
</s:ElementMenuItem>
</s:ElementMenu>
</s:ScatterViewItem>
</s:ScatterView>
<TextBlock x:Name="textMessage" Width="500" Margin="40" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontFamily="Segoe360" FontSize="17" />
</Grid>
The problem is, I get an unknown bild mistake. Key can't be NULL or something would it be in english. At the Header="{x:Static Resources....
It is exactly like in the Surface samples. I just wanted to show a message when the menu item was clickt.
Can anyone please help me? Thx
If you define this MenuItem under Resources section you need to provide it with a x:Key value. Resources can't be declared without Key -
<s:ElementMenuItem Header="{x:Static Resources:Resources.IconPhoto}"
Icon="{StaticResource IconPhoto}"
x:Key="MyMenuItem">
....
</s:ElementMenuItem>
I've got a problem with my ContextMenu in WPF. The menu is far too wide- it's the width of the items I put on it, plus about fifty-a hundred pixels. So when you open the menu, instead of being a clean list of options or buttons, there's loads of greyspace on each side. How can I fix this?
Edit: Here's my XAML for the menu:
<ContextMenu Padding="0">
<Button Content="Close Tab" Height="23" Name="closetabbutton" Width="75" Margin="0,0,0,0" Click="closetabbutton_Click" />
<TextBox Height="23" Name="renamebox" Width="75" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ClipToBounds="True" TextChanged="renamebox_TextChanged" />
<Button Content="Close Menu" Height="23" Name="closemenubutton" Width="75" Margin="0,0,0,0" Click="closemenubutton_Click" />
</ContextMenu>
The space is reserved for icons on the left, and input gesture text (e.g. Ctrl+C) on the right. This is by design.
If you wish to change this, you'll have to create your own ContextMenu style. Here's an example of how to do this:
http://www.dev102.com/2008/06/20/how-to-create-a-wpf-custom-context-menu/
Update
Further to my question comment, MenuItems would normally be used where you have used buttons. For example:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="mnuClose" Header="Close tab" InputGestureText="Ctrl+C" />
<MenuItem Name="mnuRename">
<MenuItem.Header>
<TextBox Name="txtRename" Width="100" />
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</Grid.ContextMenu>