i have no idea to solve the problem with follwing code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<XmlDataProvider x:Key="InternalData" XPath="/Workspace">
<x:XData>
<Workspace Name="Workspace" xmlns="">
<Project Name="Project 1"/>
<Project Name="Project 2"/>
<Project Name="Project 3"/>
</Workspace>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<StackPanel DataContext="{StaticResource InternalData}">
<ListBox ItemsSource="{Binding XPath=//Workspace/Project}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=#Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Text="{Binding XPath=//Workspace/Project[1]/#Name, Mode=TwoWay}"/>
</StackPanel>
</Window>
As you can see, i can change the Name of the first Project in the Workspace with the TextBox.
By changing the data, i want to start an animation to fade out the old value, change the value and start an animation to fade in the new value (e.g. opacity of "Project 1" from 1 to 0, change data and opacity of "" from 0 to 1)
If possible, i wanted to implement the solution only in XAML. But no idea. Maybe something with DataTrigger and EnterAction and ExitAction or stuff like that?
Kind regards
Shounborugh
You might want to try looking in to WPF storyboards. This is a common practice if you want to start an animation using only XAML. This is the best place to start about storyboards in WPF
http://msdn.microsoft.com/en-us/library/ms742868.aspx
This is how you can start the storyboard upon changing the text in the textbox
<TextBox Height="23" HorizontalAlignment="Left" Margin="90,44,0,0" Name="textBox1" VerticalAlignment="Top" Width="120">
<TextBox.Triggers>
<EventTrigger RoutedEvent="TextBox.TextChanged">
<BeginStoryboard>
<Storyboard>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
</TextBox>
Related
I've seen similar questions, but I still not able to do my need. I need to output checkbox's name through a label inside a user control:
Window1.xaml:
<Window x:Class="WpfBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfBinding" Title="Window1" Height="300" Width="300">
<Grid>
<CheckBox Name="checkBox1">
<local:UserControl1></local:UserControl1>
</CheckBox>
</Grid>
</Window>
UserControl1.xaml:
<UserControl x:Class="WpfBinding.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas>
<Label Content="{Binding ElementName=checkBox1, Path=Name}"></Label>
</Canvas>
</UserControl>
How to do it correctly? What lack of knowledge I have? Thanks for help.
Above solution will work, but a more direct solution for this specific problem would be to use RelativeSource binding in your user control as below:
<Canvas>
<Label Content="{Binding RelativeSource={RelativeSource AncestorType=CheckBox, AncestorLevel=1}, Path=Name}"></Label>
</Canvas>
Hope this is what you need !!!
ElementName binding works within in same XAML scope. This will work -
<Grid>
<CheckBox Name="checkBox1"/>
<Label Content="{Binding ElementName=checkBox1, Path=Name}"/>
</Grid>
But if you want to do it in different UserControl, you have to tweak a bit your code and use Tag to hold name -
<Grid>
<CheckBox Name="checkBox1">
<local:UserControl1 Tag="{Binding ElementName=checkBox1, Path=Name}"/>
</CheckBox>
</Grid>
UserControl.xaml
<Canvas>
<Label Content="{Binding Path=Tag, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=UserControl}}"/>
</Canvas>
On a sidenote, in your UserControl, you know you need to bind with ElementName = checkBox1 and that's the name only you are binding to. Its something equivalent to -
<Label Content="checkBox1"/>
I'am quite new with WPF and still trying to figure it out in all its details ;)
I have a strange issue with the button not raising its click event. I have a UserControl called PopupButton which is basically a button with a popup showed on click. The content of the popup is ContentPresenter and is binded to the dependency property called PopupContentHolder on the PopupButton.
Then on the main form I have a DataGrid with DataGridTemplateColumn where in the <DataGridTemplateColumn.CellTemplate> <DataTemplate> I placed my PopupButton. Then I assign a list box with an ItemTemplate as the content of the popup for my PopupButton.
In simple this looks as follows
<DataGrid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ColumnHeaderHeight="40"
FontSize="11"
HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Pocos}"
RowHeight="30"
SnapsToDevicePixels="True"
VerticalScrollBarVisibility="Disabled">
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="70" Header="NAme">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:PopupButton DoPopupOnMainButton="True"
Foreground="{StaticResource HeaderLinkActiveColor}"
MarkButtonOnPopup="True"
PopupBackground="{StaticResource PopupBackground}"
PopupPadding="5"
ShowDownArrow="False"
Text="Some test button">
<controls:PopupButton.PopupContentHolder>
<StackPanel>
<ListBox Background="Transparent" ItemsSource="{Binding Tenders}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Margin="0,2,0,0"
Click="Button_Click"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},
Path=DataContext.SaveCommand}"
Content="{Binding .}"
FontSize="11" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</controls:PopupButton.PopupContentHolder>
</controls:PopupButton>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
Now the problem is with the button inside the ListBox in PopupButton, Neither Click event nor Command is raised. Moreover when I put the PopupButton outside the DataGrid then everythinkg works perfect. Also when I put above list box directly in grid cell then it works.
Maybe its something wrong with my PopupButtonControl.
<UserControl x:Class="WpfApplication1.PopupButton"
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"
x:Name="userControlRoot"
Width="Auto"
Height="Auto">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<Storyboard x:Key="PopupCloseStoryBoard">
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="popup" Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.1" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PopupOpenStoryBoard">
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="popup" Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid>
<Border x:Name="brdButtonBack"
Background="Transparent"
CornerRadius="3,3,0,0"
Padding="{Binding Padding,
ElementName=userControlRoot}" />
<Button x:Name="btnMain"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="btn_Click"
Command="{Binding MainCommand,
ElementName=userControlRoot}"
Content="{Binding Text,
ElementName=userControlRoot}"
IsEnabled="{Binding IsEnabled,
ElementName=userControlRoot}" />
<Popup x:Name="popup"
MinWidth="{Binding ActualWidth,
ElementName=userControlRoot}"
AllowsTransparency="True"
Placement="Bottom"
PlacementTarget="{Binding ElementName=brdButtonBack}"
PopupAnimation="Slide"
StaysOpen="False">
<Border Background="{Binding PopupBackground,
ElementName=userControlRoot}"
BorderBrush="White"
CornerRadius="0,3,3,3"
Padding="{Binding PopupPadding,
ElementName=userControlRoot}">
<ContentPresenter Content="{Binding PopupContentHolder, ElementName=userControlRoot}" />
</Border>
</Popup>
</Grid>
I have simplified the control but the problem reproduces with that version too. The code behind for the control mostly contains dependency properties, the only logic is shown below
public partial class PopupButton : UserControl
{
//... dependency properties
public PopupButton()
{
InitializeComponent();
}
private void btn_Click(object sender, RoutedEventArgs e)
{
Storyboard s = (Storyboard)TryFindResource("PopupOpenStoryBoard");
s.Begin();
}
private void popup_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
//trick to close popup when the button inside is clicked
//this must be done with storyboard and delay
//since popup can not be closed before the event reaches clicked
//button
if (e.Source is Button)
{
Storyboard s = (Storyboard)TryFindResource("PopupCloseStoryBoard");
s.Begin();
}
}
}
Has anyone any clue what can be wrong with it?
Thanks.
I did finally solve this by rewriting PopupButton as CustomControl. There, instead of firing StoryBoard to close the popup, when the contained button is clicked I used following code
mainPopup.AddHandler(Button.ClickEvent, new RoutedEventHandler(mainPopup_ButtonClick), true);
Adding a button click handler for main popup, which will be called on the popup even if the event is already handled by the source button.
void mainPopup_ButtonClick(object sender, RoutedEventArgs e)
{
MainPopup.IsOpen = false;
}
More info about handling already handled routed events here
Maybe it is just a typo because there is a btn_Click and Button_Click event handler in your code.
Would you mind providing the code of the PopupContentHolder or maybe the whole PopupButton class?
I'm having some problems with data binding in XAML and WPF. Specifically, I'm trying to bind data from an XmlDataProvider to a ListBox.
The problem is this, when I'm in design mode in Visual Studio 2010, the xml items show up correctly, but when I run the app the listbox is just empty.
Here is what my xaml looks like. I'm not using any code behind, so this is all there is:
<Window x:Class="WpfTest9_Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="309" Width="622">
<Window.DataContext>
<XmlDataProvider XPath="Servers">
<x:XData>
<Servers>
<Server name="Server01" active="true" />
<Server name="Server02" active="false" />
<Server name="Testserver01" active="true" />
<Server name="Testserver02" active="true" />
</Servers>
</x:XData>
</XmlDataProvider>
</Window.DataContext>
<Grid>
<ListBox ItemsSource="{Binding XPath=*}" Margin="12">
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="5" Margin="5" BorderThickness="2" BorderBrush="#FFC14343">
<StackPanel Orientation="Horizontal" Margin="5">
<CheckBox IsChecked="{Binding XPath=#active}" />
<Label Content="{Binding XPath=#name}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Like I said above, the strange thing is that it looks like it's working while in design mode, but it fails to fill the listbox when I run the application. I'm not getting any error messages or warnings either.
What's wrong?
Ok, the solution was surprisingly simple.
As pointed out in this post, Listbox content not being populated with content from xml when using XmlDataProvider , all I had to do was to add an empty namespace attribute to the xml element. Like this:
<Servers xmlns="">
<Server name="Server01" active="true" />
<!-- ... -->
</Servers>
I have a listbox where I have to add about 20 static custom items. All the items are based on the same template (something like that) :
<Border>
<StackPanel Orientation="Horizontal">
<Image Source="" Height="30" />
<TextBlock Text="" VerticalAlignment="Center" />
</StackPanel>
</Border>
I don't want to repeat that 20 times in the ListBox.Items I would like to have some kind of UserControl where I could do something Like the following where I could set some custom properties :
<ListBox>
<ListBox.Items>
<MyListBoxTemplate x:Name="Item1" ItemText="Item #1" ItemImageSource="/Image1.jpg" />
<MyListBoxTemplate x:Name="Item2" ItemText="Item #2" ItemImageSource="/Image2.jpg" />
...
</ListBox.Items>
</ListBox>
But I don't wan't to create a userControl just for that!!! Is there an easy way to put that template in the Window.Resources?
Thanks
If you are ONLY using it for that SPECIFIC listbox, you can just assign the ItemTemplate property. This will need to work in conjunction with a collection of custom objects defined in your resources somewhere else. This will save you from creating a custom UserControl, but you will need an object that can be defined in XAML and a list of them in XAML anyway. To be honest, creating a UserControl is relatively painless and may be easier, but it is possible without doing so.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate TargetType="CustomObjectType">
<Border>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageSource}" Height="30" />
<TextBlock Text="{Binding TextContent}" VerticalAlignment="Center" />
</StackPanel>
</Border>
<DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
EDIT: If you are going to use it in more than one place, put the DataTemplate in your Application resources and ive it a key, then assign the ItemTemplate property to {StaticResource MyListBoxItemsTemplateKey}
Not my favorite approach since it uses the XmlDataProvider and XPath syntax (which I tend to always forget). But you can embed your static data as xml within your Window.Resources like so:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<XmlDataProvider x:Key="MyStaticData" XPath="StaticItems" >
<x:XData>
<StaticItems xmlns="">
<StaticItem>
<ItemText>Item #1</ItemText>
<ItemImageSource>/Image1.jpg</ItemImageSource>
</StaticItem>
<StaticItem>
<ItemText>Item #2</ItemText>
<ItemImageSource>/Image2.jpg</ItemImageSource>
</StaticItem>
</StaticItems>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<Grid>
<ListBox>
<ListBox.ItemsSource>
<Binding Source="{StaticResource MyStaticData}" XPath="StaticItem" />
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding XPath=ItemImageSource}" Height="30" />
<TextBlock Text="{Binding XPath=ItemText}" VerticalAlignment="Center" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Then within your ListBox bind to the XmlDataProvider you specified and use the XPath notation within the bindings to drill down to the data you want the controls to bind to.
This site has a couple good examples too:
http://vbcity.com/blogs/xtab/archive/2010/12/24/more-xpath-examples-in-a-wpf-application.aspx
Hope this helps!
i have some data saved in a xml file.
Those will be displayed in a listbox.
Now, when i change the listbox Selectedindex, i would like to update the other information in the textblock based on the selectedindex.
is there any way to do this in pure xaml?
if not, how would i bind the Textblock to the selecteditem in the listbox ?
EDIT:
How would i navigate through the Data without using the listbox? i mean using a button to move to next item and other button to move backward..!!
any help is really appreciated..
<Window x:Class="WpfSingleInstance.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<StackPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Cornsilk">
<StackPanel.Resources>
<XmlDataProvider x:Key="InventoryData" XPath="Inventory/Books">
<x:XData>
<Inventory xmlns="">
<Books>
<Book ISBN="0-7356-0562-9" Stock="in" Number="9">
<Title>XML in Action</Title>
<Summary>XML Web Technology</Summary>
</Book>
<Book ISBN="0-7356-1370-2" Stock="in" Number="8">
<Title>Programming Microsoft Windows With C#</Title>
<Summary>C# Programming using the .NET Framework</Summary>
</Book>
<Book ISBN="0-7356-1288-9" Stock="out" Number="7">
<Title>Inside C#</Title>
<Summary>C# Language Programming</Summary>
</Book>
</Books>
</Inventory>
</x:XData>
</XmlDataProvider>
</StackPanel.Resources>
<TextBlock FontSize="18" FontWeight="Bold" Margin="10"
HorizontalAlignment="Center">XML Data Source Sample</TextBlock>
<ListBox
Width="265" Height="98" x:Name="lbox" Background="Honeydew" IsSynchronizedWithCurrentItem="True">
<ListBox.ItemsSource>
<Binding Source="{StaticResource InventoryData}"
XPath="*[#Stock='out'] | *[#Number>=8 or #Number=3]"/>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="12" Foreground="Red">
<TextBlock.Text>
<Binding XPath="Title"/>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel DataContext="{StaticResource InventoryData}">
<TextBlock Text="{Binding XPath=Book/Title}"/>
<TextBox Margin="5,31,98,10" x:Name="textBoxMainDetail" Text="{Binding XPath=Book/Summary}" />
</StackPanel>
</StackPanel>
</Grid>
You could bind like this:
<TextBox Text="{Binding ElementName=lbox, Path=SelectedItem[Title].InnerText}" />
SelectedItem is an XmlElement.
EDIT: Here is a bit of sample code how to access the data of the XmlDataProvider in code behind and apply it as DataContent of a TextBox.
Change the TextBox.Text binding like this:
<TextBox x:Name="textBoxMainDetail" Text="{Binding Path=[Title].InnerText}" />
In code behind get the XML data from the XmlDataProvider and set the DataContext of the TextBox:
XmlDataProvider dataProvider = (XmlDataProvider)stackPanel.Resources["InventoryData"];
XmlElement books = (XmlElement)dataProvider.Document.SelectNodes(dataProvider.XPath)[0];
// set DataContext to an item from the child node collection
textBoxMainDetail.DataContext = books.ChildNodes[0];
Note that the StackPanel with the XmlDataProvider in its resource dictionary has now got a name. If this code shall run during application initialization (e.g. in Window constructor), the XmlDataProvider.IsAsynchronous property must be set to false.
You should now be able to change the DataContext to another indexed item of the books collection in a button click handler.
You need to set the SelectedValuePath as the 'Title' for your listbox. Then simply bind the your textBlock to the selectedValue of your listbox using elementName like this -
<ListBox Width="265" Height="98" x:Name="lbox" Background="Honeydew"
IsSynchronizedWithCurrentItem="True" SelectedValuePath="Title">
</ListBox>
<StackPanel DataContext="{StaticResource InventoryData}">
<TextBlock Text="{Binding Path=SelectedValue, ElementName=lbox}"/>
<TextBox Margin="5,31,98,10" x:Name="textBoxMainDetail" Text="{Binding XPath=Book/Summary}" />
</StackPanel>
</StackPanel>