|
Hi Karl,
Its that old friend of ours d:IsLayer="True"
Basically In the user control (in the same namespace as the main presentation project not a separate UserControls namespace) I can't seem to 'see' any of the controls that are used in the main screen in order to change their visibility ... really odd.
And these controls have a x:Name="" ... should these be plain Name=""
Cheers,
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
x:Name is fine.
If you are in the code behind of a user control, you will not see the objects in the main window.
This encapsulation and separation of responsibilities is a feature of .NET and object oriented languages.
By having the user control address the controls on the main form you are creating a dependency inversion which "normally" we try to stay away from.
If the design of your application requires this you do have several options.
1. You can get a reference to the main window, then cast it to the type your main window is, then you can reference the controls on the main window.
2. You can have the user control raise an event that the the main window services and then allow the main window to set its controls.
3. You can expose properites on the user control that the main window can bind to, that controls their visibility.
4. You can pass a reference to the controls that the user control will effect in and then the user control can control them.
I'm sure there are other ways to accomplish this.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Thanks for this Karl. Loads more learning to do now! Not sure I even know how to cast something at the moment.
I'm still at the stage where I expect to be able do things that are simply daft, you shouldn't do or can't do at all.
hmm ...
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
What language to you use? C# or VB.NET?
modified 27-Feb-21 21:01pm.
|
|
|
|
|
C# all the way ... I'm just trying this but it doesn't work yet ...
public sealed class ApplicationViewEventArgs : EventArgs
{
private Enums.ApplicationView _applicationView;
public Enums.ApplicationView ApplicationViewStatus
{
get
{
return _applicationView;
}
}
public ApplicationViewEventArgs(Enums.ApplicationView ApplicationViewStatus)
{
_applicationView = ApplicationViewStatus;
}
}
public partial class Navigator : UserControl
{
public delegate void ApplicationViewChanged(object sender, ApplicationViewEventArgs e);
public event ApplicationViewChanged ApplicationViewStatusChanged;
public Navigator()
{
InitializeComponent();
}
private void btnBrowseView_Click(object sender, RoutedEventArgs e)
{
if (ApplicationViewStatusChanged != null)
ApplicationViewStatusChanged(this, new ApplicationViewEventArgs(Enums.ApplicationView.BrowserView));
}
private void btnDatabaseView_Click(object sender, RoutedEventArgs e)
{
if (ApplicationViewStatusChanged != null)
ApplicationViewStatusChanged(this, new ApplicationViewEventArgs(Enums.ApplicationView.DataBaseView));
}
}
with this in my main window:
private void Navigator_ApplicationViewStatusChanged(object o, ApplicationViewEventArgs e)
{
lyrBrowserView.Visibility = Visibility.Hidden;
lyrDatabaseView.Visibility = Visibility.Hidden;
switch (e.ApplicationViewStatus)
{
case Enums.ApplicationView.BrowserView:
lyrBrowserView.Visibility = Visibility.Visible;
break;
case Enums.ApplicationView.DataBaseView:
lyrDatabaseView.Visibility = Visibility.Visible;
break;
}
}
the Enums look like:
public static class Enums
{
public enum ApplicationView
{
BrowserView = 0,
DataBaseView = 1,
ConfigurationView = 2
}
}
This is the first time I've even delt with events! Not going well ...
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
I'm going to just spit out questions and comments, not in any order.
If you are swapping which user control is displayed, would a TabControl work better for you?
Is there a reason to put the buttons in a user control rather than just on the main form?
If you're using an event, you should use a RoutedEvent rather than a regular event in WPF. This way the child objects can bubble the event up the ElementTree.
Would a menu work for selection purposes?
There is another way to accomplish this also. You can use buttons in your user control that use RoutedCommands. In the button CommandParamenter load the ApplicationView enum value for that button. Then, set up a listener called CommandBinding in the main window. You can use one of the RoutedCommands supplied with WPF or create your own.
There are many articles on RoutedCommands here on Code Project. Suggest reading up on these. They enable decoupling of the command and the handler.
I also recently posted this on my blog: http://karlshifflett.wordpress.com/2008/02/24/wpf-sample-series-wpf-mvc-tabcontrol-mdi-and-commandbindings/[^]
modified 27-Feb-21 21:01pm.
|
|
|
|
|
I suppose any of those things are doable. I'm just swapping layers (or rather trying to swap layer visibility) I just wanted to put them in a user control in order to keep things tidy and it should be simple.
There is something i'm just totally missing in the code I posted. I like buttons more than menus too
Do you know why this isn't working?
public sealed class ApplicationViewEventArgs : EventArgs
{
private Enums.ApplicationView _applicationView;
public Enums.ApplicationView ApplicationViewStatus
{
get
{
return _applicationView;
}
}
public ApplicationViewEventArgs(Enums.ApplicationView ApplicationViewStatus) : base()
{
_applicationView = ApplicationViewStatus;
}
}
this is obviously the whole deal but its always returning null ... is there a "using System.blah" for events that I should be using?
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
I don't see anything wrong, but my strength is VB.NET.
Maybe Pete can look at this for you.
Jammer wrote: this is obviously the whole deal but its always returning null
Not sure why these event args are null.
Did you set up an event handler for them in the main form?
Since you are new to WPF, you may want to take a step back and read up on RoutedCommands . This is the best solution for these buttons.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Hi Karl,
Thanks for that ... its weird isn't it ... i'm going backwards and forwards with this code and its just never getting evaluated and never grabbing the enums ... I have this in the main form that never gets called due to the if{} always being null ...
private void Navigator_ApplicationViewStatusChanged(object o, ApplicationViewEventArgs e)
{
lyrBrowserView.Visibility = Visibility.Hidden;
lyrDatabaseView.Visibility = Visibility.Hidden;
switch (e.ApplicationViewStatus)
{
case Enums.ApplicationView.BrowserView:
lyrBrowserView.Visibility = Visibility.Visible;
break;
case Enums.ApplicationView.DataBaseView:
lyrDatabaseView.Visibility = Visibility.Visible;
break;
}
}
I can't see anything i'm doing differently to any of the examples I'm finding online. I'm going to take a look at RoutedCommands I think. This is doing my head in ...
Thanks chap.
Pete, if you can shed any light on this I'll be forever in your debt!
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
Jammer - sorry that it's taken so long for me to get to this. It's the first time I've been online in a couple of days. Have you actually hooked the event up to anything in the main form? If you want to send me the project (zipped up of course), I'll be more than happy to take a look at it.
|
|
|
|
|
Hey Pete,
Wow, that is an incredibly nice offer. I actually persisted and got my code working after some more head scratching. I was being extremely daft! I had given my user control an x:Name="" but only in the controls XAML file, not the main window XAML file where it is actually being instantiated. As soon as I'd done that all was well.
I'm just looking at some other UI code at the moment. I'm just in the process of building some new buttons and implementing some RoutedCommands.
Been quite a successful day of coding so far. I've practically finished a lot of the UI styling (using Blend) and I've implemented my first object serialization exercise ... bloody code worked first test! So my database is now persisted on disk! wooo ...
I'm loving C# ... XAML is still a tad confusing though.
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
That's excellent. Sorry I couldn't get back to you earlier on this.
|
|
|
|
|
Not at all chap. You've been a great help!
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
Can the dreaded nullable combo-box be created in WPF. Of course with all the databinding enabled etc?
Seriously, I'm wondering why it hasn't already been done since this was a huge bug-bear with Windows Forms.
|
|
|
|
|
Ed.Poore wrote: Can the dreaded nullable combo-box be created in WPF.
Ed,
Dumb question. What is the dreaded nullable combo-box?
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Not a dumb question although a quick Google would have given you the idea. Imagine any field where you want to select an item for a relationship in a drop-down or nothing.
E.g. you're assigning a bug to a user in your database. You use LINQ or whatever to pull the users from the database, and these are bound to the combobox so you get a list of all the users. But it should also have (None) or something similar so that if you select that item then the relationship is set to null.
There's been no easy workaround this problem in WinForms so hopefully the magic that is WPF would be able to do it
|
|
|
|
|
You can add the extra row in the data in your business layer or data layer, or simply extend the combobox to function like the ASP.NET dropdown control that has this built in.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Karl Shifflett wrote: You can add the extra row in the data in your business layer or data layer
That's those hacks I mentioned. Not really a good design.
Karl Shifflett wrote: extend the combobox to function like the ASP.NET dropdown control that has this built in
I wanted to see some code
|
|
|
|
|
2 thoughts. 1 - do this in exactly the way that Karl suggested and create your own control, or 2 - use an Extension method that would look something like this:
public static void NullableDataSource<T>(this ComboBox source, IList<T> binding)
where T : class, new()
{
if (binding != null)
{
binding.Insert(0, "<Null>");
}
source.DataSource = binding;
} I've not tried this out, I'm just typing the code off the top of my head, but there's no reason that this (or something like this) wouldn't work.
|
|
|
|
|
It does work, on the surface. However if you try and access the lists through other methods then it messes up (i.e. through indicies).
I was thinking that there'd be an ice elegant way to create a combo box in WPF which allows it to be set as nullable, rather than having to modify the underlying data.
Perhaps creating a new items template thingy and inserting a control there which if selected is null. I.e. the underlying datasource is not modified at all.
I'll see what I can do when I get the chance. Just wondering if someone had come up with a solution already.
|
|
|
|
|
Hi All,
I'm just adding in ToolTips to a chart I'm building in WPF. The TargetType is set to {x:Type ToolTip} and the style definition is placed in the <usercontrol.resources> section of the XAML.
Running the application and navigating to the screen with the chart in works ok (no compile error) but the tooltip is not styled as per the definition. Going into Blend and looking at the UserContol is ok but when I click on the [Edit Resource] button for [System.Windows.Controls.ToolTip] resource I get the following error:
'ToolTip' cannot have a logical or visual parent.
Any ideas would be great.
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
Can you post the XAML?
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Hi Karl,
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:igCA="http://infragistics.com/Chart"
xmlns ="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Occam.ZebraDemo.WPFWindows.Zebra3DPieChart"
x:Name="ZebraCleaningChartControl"
Width="605" Height="454">
<UserControl.Resources>
<!-- ToolTip Style -->
<Style TargetType="{x:Type ToolTip}">
<Setter Property="Background" Value="#FF0000" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border CornerRadius="4" Background="Transparent">
<ContentPresenter Margin="6,4,6,4" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<igCA:XamChart Margin="0,0,0,0" Name="ZebraCleaningChart" View3D="True" Style="{DynamicResource Zebra_XamChartRoyalVelvet}" BorderThickness="0,0,0,0">
<igCA:XamChart.Legend>
<igCA:Legend Visible="False" />
</igCA:XamChart.Legend>
<!-- Data Points and Chart Parameters -->
<igCA:XamChart.Series>
<igCA:Series Label="Cleaning Results" ChartType="Pie">
<igCA:Series.DataPoints>
<igCA:DataPoint Label="Good Records" Value="30" />
<igCA:DataPoint Label="Bad Records" Value="10" />
<igCA:DataPoint Label="Unknown" Value="20" />
</igCA:Series.DataPoints>
</igCA:Series>
</igCA:XamChart.Series>
<!-- 3D Transform (Rotation etc ...) -->
<igCA:XamChart.Transform3D>
<Transform3DGroup>
<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
<ScaleTransform3D ScaleX="1" ScaleY="1.0000000000000002" ScaleZ="1.0000000000000002"/>
<RotateTransform3D d:EulerAngles="-28.387969869694,9.27192578600399,-3.5230603833372">
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Angle="29.766" Axis="-0.942,0.334,-0.039"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
</Transform3DGroup>
</igCA:XamChart.Transform3D>
</igCA:XamChart>
</Grid>
</UserControl>
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
Jammer,
Take a close look at the colors. I added the alpha channel to each of your hex colors.
The Background of the Border was Transparent, I made it Black and the ToolTip now shows up.
Not sure why Blend blows up. I'm using Blend 2.5, got the same thing. I would send your example to the Blend team.
The below template works fine and shows the tooltip at run-time.
<UserControl.Resources>
<!-- ToolTip Style -->
<Style TargetType="{x:Type ToolTip}">
<Setter Property="Background" Value="#FF000000" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="Foreground" Value="#FFFFFFFF" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border CornerRadius="4" Background="#FF000000" >
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Ahhh, ok.
I've just amended my code to reflect the changes you detail and my ToolTip still isn't applying the styling.
My tooltip was always showing up just not with the style template applied to the tooltip.
This is really frustrating at the moment.
Thanks for the tips ... will keep on trying to get this working. I'm kida running out of time trying to get a simple tooltip running properly! feck!
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|