hey there,
i have written a custom control for my App so things get a little bit easier for me,and so far it worked great , now i wanted to bind some data to the wrapped content but Output says that i have a binding error and my "Items" property is searched at "CLIENT.UI.SinglePageControl" instead of "CLIENT.MainPage"....
<phone:PhoneApplicationPage
x:Class="CLIENT.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:CLIENT.UI"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<Grid>
<ui:SinglePageControl HeaderTitle="Connections">
<ui:SinglePageControl.PageContent>
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" Background="Blue" SelectionChanged="MainListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Orientation="Horizontal">
<Image Source="UI/PICS/list_connection.png"/>
<TextBlock Text="{Binding ItemText}" TextWrapping="Wrap" Foreground="Black"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ui:SinglePageControl.PageContent>
</ui:SinglePageControl>
</Grid>
Try giving your control an x:Name value and then in your binding statement include ElementName=<x:Name>
<phone:PhoneApplicationPage
x:Name="pa"
x:Class="CLIENT.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:CLIENT.UI"
mc:Ignorable="d"
d:DesignWidth="480"
d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape"
Orientation="Portrait" shell:SystemTray.IsVisible="True">
<Grid>
<ui:SinglePageControl HeaderTitle="Connections">
<ui:SinglePageControl.PageContent>
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items, ElementName=pa}" Background="Blue" SelectionChanged="MainListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Orientation="Horizontal">
<Image Source="UI/PICS/list_connection.png"/> <TextBlock Text="{Binding ItemText, ElementName=pa}" TextWrapping="Wrap" Foreground="Black"/>
</StackPanel> </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ui:SinglePageControl.PageContent>
</ui:SinglePageControl>
</Grid>
Without seeing how you're setting data contexts, etc it's difficult to tell, but judging by the details you've given, at the level of your ListBox your data context is the SinglePageControl.PageContent. Ordinarily, the data context of the parent (the MainPage) would be inherited down the visual tree, so the fact that it's not in this case implies that SinglePageControl.PageContent is setting it's own data context. If you don't need it it, then simply remove the code (this.DataContext = this; for example) that is setting it and the data context will then be inherited.
If you have good reason for setting a data context at the page content (which would seem perfectly reasonable), then you will need to provide a way of passing that information down, but we'll need to know a bit more about what data comes from where in order to give a good solution.
Related
I am having trouble with the Xaml passer throwing a 'Type Not Defined' exception after I add a x:Name attribute to a user control declaration which is inside another user control.
<UserControl x:Class="LoginView"
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:vm="clr-namespace:PowderKegSoftware.Artisan.Client.Authentication"
xmlns:ctrl="clr-namespace:PowderKegSoftware.Artisan.Client.Ui.Controls;assembly=CommunalUi"
xmlns:auth="clr-namespace:PowderKegSoftware.Artisan.Client.Authentication"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:LoginViewmodel,
IsDesignTimeCreatable=False}"
d:DesignHeight="693" d:DesignWidth="1080">
<UserControl.Resources>
---------------------
</UserControl.Resources>
------------------------
<Border BorderThickness="0">
<Border.Background>
<ImageBrush ImageSource="{Binding BackgroundImage}"
Stretch="None" />
<TextBlock Grid.Column="0"
Grid.Row="1"
Text="{Binding UsernameLabelText}"
Style="{StaticResource TextBlockBaseStyle}"/>
<ctrl:ArtisanComboBox Grid.Column="0"
Grid.Row="2"
Height="30"
TabIndex="10"
Style="{StaticResource ArtisanComboBoxDefaultStyle}"
DataContext="{Binding UsernamesVm}" />
<TextBlock Grid.Column="0"
Grid.Row="3"
Text="{Binding PasswordLabelText}"
Style="{StaticResource TextBlockBaseStyle}"
Margin="0 20 0 0"/>
------------------
This all works just fine until I try and add the x:Name attribute to the <ctrl:ArtisanComboBox ... declaration.
<ctrl:ArtisanComboBox Grid.Column="0"
Grid.Row="2"
x:Name="ChoosableUserNames" <!-- Throws a 'Type Not Defined' error. -->
Height="30"
TabIndex="10"
Style="{StaticResource ArtisanComboBoxDefaultStyle}"
DataContext="{Binding UsernamesVm}" />
I have tried using x:Name= and just Name= but neither complies. I want to name this declaration so I can use FocusManager.FocusedElement="{Binding ElementName=ChoosableUserNames} to set the focus on this control when the view is renered.
Thanks for any help you can give.
I am using MVVM application and there is something that don't understand..
What is the difference between StackPanel visibility and Grid Visibility.
if I have this Grid...
<UserControl x:Class="Envitech.Setup.Presentation.Views.MonitorScreenViews.MonitorAlertViews.MonitorAlertView" 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" mc:Ignorable="d" d:DesignHeight="438" d:DesignWidth="842" xmlns:popup="clr-namespace:Envitech.Setup.Presentation.Views.GlobalViews">
<DockPanel DataContext="{Binding MonitorAlertViewModel}" Width="824" HorizontalAlignment="Left" VerticalAlignment="Top" Height="435">
<Grid DataContext="{Binding CurrentMonitorAlert}" Height="422" Visibility="{Binding Path=NoMonitorsMessageVisibility, Converter={StaticResource visibilityConverter}}">
<Label Content="Value" Height="28" HorizontalAlignment="Left" Margin="10,103,0,0" VerticalAlignment="Top" />
</Grid>
</DockPanel>
</UserControl>
visibility does not work, but if i do it this way...
<UserControl x:Class="Envitech.Setup.Presentation.Views.MonitorScreenViews.MonitorAlertViews.MonitorAlertView" 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" mc:Ignorable="d" d:DesignHeight="438" d:DesignWidth="842" xmlns:popup="clr-namespace:Envitech.Setup.Presentation.Views.GlobalViews">
<DockPanel DataContext="{Binding MonitorAlertViewModel}" Width="824" HorizontalAlignment="Left" VerticalAlignment="Top" Height="435">
<StackPanel Visibility="{Binding Path=NoMonitorsMessageVisibility, Converter={StaticResource visibilityConverter}}">
<Grid DataContext="{Binding CurrentMonitorAlert}" Height="422">
<Label Content="Value" Height="28" HorizontalAlignment="Left" Margin="10,103,0,0" VerticalAlignment="Top" />
</Grid>
</StackPanel>
</DockPanel>
</UserControl>
visibility works just fine.
Why?
The DataContext of the Grid is CurrentMonitorAlert. The DataContext of the StackPanel is MonitorAlertViewModel. Thus, the binding to NoMonitorsMessageVisibility is resolving against the wrong thing in your Grid case.
Setting the DataContext like that all over your view is somewhat unorthodox. Normally when doing MVVM you let WPF handle setting the DataContext (except possibly at the root level) and use deeper paths in your bindings if necessary. You might want to consider taking that approach.
I'm having problems setting the DataContext for all fields that are inside a stackPanel. What I would like to do is set the Data Context as vm:ViewModel. But it's not working and when I ask VS for assistance with DataBinding it Displays the TextBox.DataContext inside the TextBox. Is there a way to only set it once or do I have to set it for each control?
<StackPanel DataContext="vm:ViewModel">
<TextBox Text="{Binding FirstNumber}" HorizontalAlignment="Left" Height="23" Margin="206,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
<TextBox.DataContext>
<vm:ViewModel/>
</TextBox.DataContext>
</TextBox>
</StackPanel>
You need to get your DataContext to refer to an instance of your ViewModel.
DataContext="vm:ViewModel" is not creating an instance of the ViewModel...it's just setting a string.
Use Property Element syntax instead:
<StackPanel>
<StackPanel.DataContext>
<vm:ViewModel/>
</StackPanel.DataContext>
<TextBox Text="{Binding FirstNumber}" HorizontalAlignment="Left" Height="23" Margin="206,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
</StackPanel>
And if you do that, then there's no need/in fact it's probably wrong to create another one in your TextBox.DataContext...you just want to inherit the DataContext of the StackPanel.
I'll just show you another way to create a ViewModel and to refer to the instance of it so you have a bigger picture.....that is to create it in resources, and then refer to that resource in the binding...here's an example:
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:WpfApplication8"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<vm:ViewModel x:Key="myviewmodel"/>
</Window.Resources>
<StackPanel x:Name="stackp" DataContext="vm:ViewModel">
<TextBox Text="{Binding Source={StaticResource myviewmodel}, Path=FirstNumber}" HorizontalAlignment="Left" Height="23" Margin="206,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
</StackPanel>
</Window>
Another example that sets the DataContext at a higher level in the tree:
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:WpfApplication8"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:ViewModel/>
</Window.DataContext>
<StackPanel>
<TextBox Text="{Binding FirstNumber}" HorizontalAlignment="Left" Height="23" Margin="206,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
</StackPanel>
</Window>
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
Title="MainWindow" Height="350" Width="525">
<Grid>
<sdk:TreeView Height="197" HorizontalAlignment="Left" Margin="242,80,0,0" Name="treeView1" VerticalAlignment="Top" Width="175" DataContext="{Binding}">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Childen}">
<StackPanel>
<TextBlock Text="{Binding Path=Value}"/>
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>
I keep getting this error when I build the solution.
The tag 'TreeView' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk'. Line 8 Position 10.
In WPF you don't need to use sdk: for TreeView. Simple put <TreeView ... this should work.
Using the Image Source Property just works, if I'm not inside a DataTemplate.
Otherwise he cannot find the picture which is in another assembly named "Images".
XAML, that works. I can see the Image, holded by the "Images" assembly:
<UserControl x:Class="Views.ViewUserInfo"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5">
<TextBlock Text="Authorized: "/>
<TextBlock Text="{Binding Path=IsAuthorized, Mode=OneWay}" VerticalAlignment="Center"/>
<Image Width="16" Height="16" Source="/Images;Component/Img16/Ok.png" />
</StackPanel>
</StackPanel>
</UserControl>
Does not work:
<UserControl x:Class="Views.ViewUserInfo"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<DataTemplate DataType="{x:Type System:Boolean}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="DataTemplate has been found " />
<Image Width="16" Height="16" Source="/Images;Component/Img16/Ok.png" />
</StackPanel>
<DataTemplate.Resources>
<!--simplyfied, Triggers removed...--->
</DataTemplate.Resources>
</DataTemplate>
</UserControl.Resources>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5">
<TextBlock Text="Authorized: "/>
<ContentPresenter Content="{Binding Path=IsAuthorized, Mode=OneWay}" VerticalAlignment="Center"/>
<!--IsAuthorized.GetType() = typeof(System.Boolean)-->
</StackPanel>
</StackPanel>
</UserControl>
He's actually in the DataTemplate, because he shows me the Text "DataTemplate has been found" but i cannot see any picture..
Whats the problem here?
You said you see the text box, how can that be, your template is empty, your StackPanel is just a resource in your DataTemplate. Try removing the <DataTemplate.Resources> and </DataTemplate.Resources> lines or maybe add your <!--simplyfied, Triggers removed...--->.
Dont use ContentPresenter. Use ContentControl.
<ContentControl Content="{Binding Path=IsAuthorized, Mode=OneWay}"
VerticalAlignment="Center"/>