XAML User Control not showing - c#

I have here a User Control where I'd like to overlay over my current area. Except it isn't showing up.
Here is my code for SpatialMode.xaml:
<UserControl x:Class="FilteringModule.View.SpatialFilterMode"
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"
MouseDown="UserControl_MouseDown"
MouseUp="UserControl_MouseUp"
MouseMove="UserControl_MouseMove">
<Canvas x:Name="SpatialCanvas" Background="Wheat">
<Border
x:Name="dragSelectionBorder"
BorderBrush="Blue"
BorderThickness="1"
Background="LightBlue"
CornerRadius="1"
Opacity="0.5"
/>
</Canvas>
</UserControl>
And where I call it:
public void ShowSpatialFilterMode()
{
Console.WriteLine("SHOWING SPATIAL FILTER MODE?");
_spatialFilterMode = new SpatialFilterMode();
_spatialFilterMode.Visibility = Visibility.Visible;
}
It writes to the console so I know it's hitting it correctly, except it's not showing?
Any help would be GREATLY appreciated.
Thanks!

Where are you actually inserting it into the visual tree?
Grid.Children.Add(_spatialFilterMode);

Do you have to add the control to some parent container?

Related

Using WPF in an ElementHost control - pass data from the c# Control's constructor to the underlying XAML to allow for different instances

Running off a tutorial from CodeProject I've succeeded in adding a WPF item to my Winforms project. My WinformsProject adds a slightly altered version of ElementHost, which contains a xaml object as a child from a separate project (with the alterations to ElementHost seemingly just to pass property and methods between the two projects).
My XAML code is:
<UserControl x:Class="WindowsFormsControlLibrary1.RoundedButtonWithSVG"
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" xmlns:windowsformscontrollibrary1="clr-namespace:WindowsFormsControlLibrary1"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="250">
<Grid>
<Button x:Name="myButton" HorizontalAlignment="Left" Background="White" Height="50" VerticalAlignment="Top" Width="250" BorderBrush="#FFBFBFBF" Click="myButton_Click">
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Button.Resources>
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
<Canvas Name="svg117" Width="32" Height="32" >
<!--Unknown tag: sodipodi:namedview-->
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path115" Fill="#FF008A9F" StrokeThickness=".4025" Stroke="#FF008A9F">
<Path.Data> <!--Below is the SVG for an icon-->
<PathGeometry Figures="m31.63 0.27366c-0.12545-0.088189-0.29069-0.098564-0.4267-0.027534l-30.786 16.139c-0.19792 0.10375-0.27291 0.34517-0.16751 0.53991 0.048232 0.08899 0.12898 0.15682 0.22597 0.18955l9.4117 3.2015 0.17011 0.05507 2.6795 8.2814c0.04291 0.13288 0.1533 0.23384 0.2911 0.26696 0.03167 0.0072 0.06411 0.01117 0.09663 0.01117 0.10767 0 0.21091-0.0419 0.28704-0.11692l5.5775-5.4817 8.2128 2.7833c0.11327 0.03911 0.23872 0.02634 0.34144-0.03512 0.10272-0.06066 0.17295-0.16281 0.19203-0.27933l4.0599-25.14c0.02395-0.14964-0.04019-0.29968-0.16564-0.38747zm-30.003 16.381 26.809-14.053c0.0016-0.0012 0.0045-7.981e-4 0.0057 7.981e-4 0.0012 0.0016 8.12e-4 0.00439-8.12e-4 0.00559l-18.205 16.976-8.607-2.9218c-0.00231-7.98e-4 -0.00349-0.0032-0.00268-0.0056 2.842e-4 -7.98e-4 8.12e-4 -0.0016 0.00146-2e-3zm9.2038 3.4745 17.873-16.667c0.0016-0.0016 0.0041-0.0016 0.0057 0 2e-3 0.0012 2e-3 0.00399 4.06e-4 0.00559l-13.97 17.868c-0.0311 0.03871-0.05387 0.0834-0.06699 0.13129l-1.5805 5.6265c0 2e-3 -0.0018 4e-3 -0.0041 4e-3 -0.0022 0-0.0041-2e-3 -0.0041-4e-3zm3.077 7.0571 1.4303-5.0918 2.7969 0.94773-4.2223 4.1481c-0.0022 3.99e-4 -0.0043-7.98e-4 -0.0048-0.0032-4.1e-5 -3.99e-4 -8.1e-5 -3.99e-4 -8.1e-5 -7.98e-4zm13.097-1.9821-11.277-3.8221 14.987-19.168c8.12e-4 -2e-3 0.0028-0.00279 0.0049-2e-3 2e-3 7.981e-4 0.0028 0.00279 2e-3 0.00479l-3.712 22.984c-4.06e-4 2e-3 -0.0024 0.0036-0.0049 0.0032z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Canvas>
</Viewbox>
</Button>
</Grid>
</UserControl>
Essentially the above is just a simple button, with rounded corners and an SVG image (which would all make our UI Girl exceedingly happy). Now I need a bunch of these, each with different text and images. My question is, can I somehow override the xaml settings based on fields from the c# constructor? So in this case, can I override the Figures property of the PathGeometry in the Xaml to set whatever image I need for the given button? Something like the following as the .xaml.cs file
public partial class ComboBoxWithGrid : UserControl
{
public ComboBoxWithGrid(string imageString)
{
this.boundImageStringProperty = imageString;
InitializeComponent();
}
public string boundImageStringProperty = ""; //Can I Inject this into the xaml in any way?
public Action buttonClickEvent;
private void button_Click(object sender, RoutedEventArgs e)
{
buttonClickEvent();
}
}
Doing the above would let me use the one xaml object for most of my buttons, just with different constructor arguments but I'm afraid I'm not XAML Literate enough to figure any of this out, and most guides I find online detail how to send data from the xaml constructor to the c# base (not the other way around). Is any of this possible?

How to set up XAML View Content in Different XAML

I just programm a Windows Universal App and I want to set up an
empty MainView.xaml witch provides the content from different User Control xamls just like in javafx and switch then on the fly in the MainViewxaml.cs like:
Pseudo Code:
this.Content = Login.xaml
Main.xaml Pseudo Code:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<UserControl x:Name="UserControl"/>
</Grid>
My Question is:
How can I do this in a Windows Universal app ?
Use a frame and pages. Or if you don't want to do that, use a ContentControl.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ContentControl x:Name="ContentControl">
<UserControl x:Name="UserControl"/>
</ContentControl>
</Grid>
And than you can say ContentControl.Content = new YourUserControl();

Change between pages in WPF

I want to make a layout like the one used in any website - the header, sidebar and footer stay the same but the center part. I have multiple pages/windows to show in a wpf blend C# application and they are totally different. For example, stackoverflow has a layout for the homepage and another one for each Question. Here's another exemple:
I had to do that in a previous project and I used a single grid layout and then, for each page, I had to hide() all of them and show that each one on top -
What's the trick? How can I do the same thing in a wpf application? In a typical C# application I would have to open a child window each time but that seems ugly these days.
Thank you in advance!
If you are going to use Pages in WPF, then you will need to read the Navigation Overview page on MSDN. In short however, you can navigate between Pages in a WPF Application by using the NavigationService Class. To change the page from code behind, you could do something like this:
NextPage page = new NextPage();
NavigationService.Navigate(page);
To let the users change the Page, you can use the Hyperlink Class in your Pages:
<Hyperlink NavigateUri="pack://application:,,,/AppName;component/Pages/NextPage.xaml">
Navigate to Next Page
</Hyperlink>
To get your desired page setup, you will have to load your Pages into a Frame, which you can then layout wherever you like in MainWindow.xaml:
<Frame Source="pack://application:,,,/AppName;component/Pages/SomePage.xaml" />
Sounds like you need a custom usercontrol and some databinding.
You can declare DataTemplates in XAML as resources with the model type as key, so that WPF chooses the correct DataTemplate automatically:
Have a main ViewModel, which exposes a ImageSourceViewModel property. This property would either return a CameraSourceViewModel or a FileSourceViewModel, as appropriate.
In your page, the DataContext would be the main ViewModel, and you'd have XAML like this:
Then,
<Page x:Class="Page1"
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:my="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page1">
<Page.Resources>
<DataTemplate DataType="{x:Type my:CameraSourceViewModel}">
<my:CameraSourceView/>
</DataTemplate>
<DataTemplate DataType="{x:Type my:FileSourceViewModel}">
<my:FileSourceView/>
</DataTemplate>
</Page.Resources>
<Grid>
<ContentControl Content="{Binding ImageSourceViewModel}"/>
</Grid>
I should point out that this example uses the MVVM pattern to allow the viewmodel layer to decide on the content in the middle. Hopefully this is clear enough, if not, give me a shout and I'll try to expand it!
Let's say I have main view model where I've created a CurrentPage property that will tell which page you want to display.
/// <summary>
/// Returns the page ViewModel that the user is currently viewing.
/// </summary>
public ViewModelBase CurrentPage
{
get { return _currentPage; }
private set
{
if (value != _currentPage)
{
if (_currentPage != null)
_currentPage.IsCurrentPage = false;
_currentPage = value;
if (_currentPage != null)
_currentPage.IsCurrentPage = true;
RaisePropertyChanged(() => CurrentPage);
}
}
}
And in your xaml you can bind your page under some control. Let's say I am doing it inside a Border element.
<!-- CURRENT PAGE AREA -->
<Border Background="White" Grid.Column="1" Grid.Row="0">
<HeaderedContentControl Content="{Binding Path=CurrentPage}"
Header="{Binding Path=CurrentPage.DisplayName}" />
</Border>
You can define view to your view model in resources just like this:
(partially complete XAML)
<UserControl x:Class="BAT.View.BATWizardView"
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:view="clr-namespace:BAT.View"
xmlns:viewmodel="clr-namespace:BAT.ViewModel"
mc:Ignorable="d"
d:DesignHeight="350" d:DesignWidth="600">
<UserControl.Resources>
<!-- These four templates map a ViewModel to a View. -->
<DataTemplate DataType="{x:Type viewmodel:MyComparisonViewModel1}">
<view:MyView1 />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodel:MyComparisonViewModel2}">
<view:MyView2 />
</DataTemplate>
</UserControl.Resources>
<Grid>
<Border Background="White" Grid.Column="1" Grid.Row="0">
<HeaderedContentControl Content="{Binding Path=CurrentPage}"
Header="{Binding Path=CurrentPage.DisplayName}" />
</Border>
</Grid>
</UserControl>
See if that helps.

Create a simple UserControl

i'm trying to create a simple Windows Store App.
I want to reuse some "code" in many pages.
For example i need to reuse someting like this in more than one page..
<StackPanel>
<TextBlock Text="Name"/>
<TextBox x:Name="edtNome"/>
Maybe the best method is using "UserControl"...but i can't realize how!
i've created mine MyUC.xaml
<UserControl
x:Class="Crud.View.MyUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Crud.View"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<StackPanel>
<TextBlock Text="Name"/>
<TextBox x:Name="edtName"/>
</StackPanel>
But now?
I want to put it in my Page.xaml (and in many other), and access the "edtName" from page.xaml code behind.....
what i have to do?
Something like this
in xaml use a binding path. Add an x:Name for your control. ElementName=me 'me' will be the name given to your control
<TextBox x:Name="edtName" Text="{Binding Path=EditName, ElementName=me, Mode=Default}" ..../>
in that code behind add
public string EditName
{
get { return (string)GetValue(EditNameTextProperty); }
set { SetValue(EditNameTextProperty, value); }
}
public static readonly DependencyProperty EditNameTextProperty =
DependencyProperty.Register("EditName",
typeof(string),
typeof(YourClassNameHereForThisControl),
new FrameworkPropertyMetadata(""));

MouseDown event of image in usercontrol not fireing

I made a usercontrol in WPF with an image in it. I declared a MouseDown event for this image:
<Image x:Name="imgState" Height="300" Width="300" MouseDown="imgState_MouseDown" OpacityMask="#00000000" />
I placed this usercontrol on my application form, but the event isn't fireing. I'm pretty new to WPF and I read about RoutedEvents but I don't really understand it. I would be happy if someone could help and explain this to me!
Update
Changing to PreviewMouseDown didn't fire the event too. I tried setting the background to transparent and even tried with a blank 300x300 image. The grid workaround doesn't fire the event too. Here is how my code behind looks like:
private void imgState_MouseDown(object sender, MouseButtonEventArgs e)
{
//Some code here
}
Update 2
Here is my whole XAML file:
<UserControl x:Class="TicTacToe.controls.SingleField"
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="300">
<Grid>
<Image x:Name="imgState" MouseDown="imgState_MouseDown" Height="300" Width="300" Stretch="None" OpacityMask="#00000000"/>
</Grid>
</UserControl>
I removed the source again because I set one from code behind at runtime and adding a transparent/clear image didn't helped.
You probably want PreviewMouseUp instead of MouseDown event
<Image x:Name="imgState" Height="300" Width="300"
PreviewMouseUp="ImgState_OnPreviewMouseUp"
PreviewMouseDown="ImgState_OnPreviewMouseDown"/>
Either of the two, you can capture the event from there.
If the answer above does not help:
Not a very nice solution but does work so many times:
Wrap your image with a grid on which you will have your event...
<Grid MouseDown="imgState_MouseDown">
<Image/>
</Grid>
Okay I solved the problem myself.
The problem was the setting OpacityMask="#00000000" that prevented the image from appearing so there were, as #lll said, nothing to hit. I don't know when the setting was set, but I think it happened automatically while expanding the Representation tab.
Thanks for helping me!

Categories