|
I am not able to understand why are you using the TextChanged events, and why are you inserting and removing items there. You seriously need to make changes in your code. That's really bad way of programming.
I think you don't want to use any button to add items, fine, you can use the LostFocus event of the TextBox so that after writing in the TextBox, when the focus on the TextBox is lost, you can then add items. TextChanged event is not the right way.
This maybe the reason for that exception.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
As Tarun tried to explain, this is really the wrong way to tackle this problem. You're trying to write a WPF application like a WinForms one, and that defeats the purpose entirely.
The key to WPF is Data Binding... The entire interface revolves around it, and if you switch your mind to the right track, it'll make your life much easier. All of that "glue" to connect controls, keep things synchronized, turn things on and off... All of that can be pretty much automatic.
First of all, you should try to AVOID giving names to your controls. If you have to refer to a control from the code-behind, you're either doing something really weird/original, or you're just doing it wrong.
1) Create a data model class... Just a simple class that contains a few properties to store the state of your GUI. In your situation, I think you'll need properties for:
a) A list representing the Directives. I'd type this as an ObservableCollection<Directive> to make sure updates are processed correctly.
b) A Directive representing the selected item ("SelectedDirective" maybe).
2) Set the DataContext of the window (Or anything that contains all of the related controls) to this model class, so the bindings will reference it
3) Bind the controls:
a) The ItemsSource of the listbox should bind to your list property
b) The SelectedItem of the listbox should bind to your SelectedDirective property, with Mode=TwoWay
c) The textboxes (txtDirectiveName, txtDirectiveDescription - Though you should un-name them after you do this) should bind to "SelectedDirective.DirectiveName" and "SelectedDirective.DirectiveDescription"
d) The delete button's "IsEnabled" property should bind to SelectedItem. For this, you need a converter that will take an object and return true if it's non-null.
e) The delete button's event handler can be as simple as Directives.Remove(SelectedDirective) .
See how this works? The code-behind never refers directly to GUI controls, except to set the DataContext. The GUI does its own thing, and just reads and writes data to/from the underlying model.
|
|
|
|
|
That's a good answer. Rocky should use the powerful WPF features here. See his reply to my answer and the way he inserts the item.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
Yeah, I noticed... Definitely WinForms-style.
|
|
|
|
|
Definitely a Good Answer.
Regards - Kunal Chowdhury | Microsoft MVP (Silverlight) | CodeProject MVP | Software Engineer
|
|
|
|
|
Ok, i did this by using Binding method and its working fine...
But could u tell me, how can i read the data from that listbox in my code, because when am passing a soap request i need to read the DirectiveName and Descriptionn data seperately,so how can i do this...
|
|
|
|
|
You don't. Your code should never have to touch the ListBox. The ListBox's SelectedItem property binds to a property in your model, and you read THAT property to get the current value.
|
|
|
|
|
Is it possible to put controls in app resources and use then as elements inside a StackPanel ?
A bit of context: I have a UserControl which I use like this:
<Window ...
xmlns:local="clr-namespace:CRRT" ...>
<local:QueryControl>
<ScrollViewer>
<StackPanel>
<local:FeatureSelectionControl x:Key="GroupOwnerCRDSCode" Table="GroupOwnerCRDSCode" Label="Customer Group" Margin="12,12,18,9.999">
<local:FeatureSelectionControl.SelectStatement>
SELECT blablabla
</local:FeatureSelectionControl.SelectStatement>
</local:FeatureSelectionControl>
<local:FeatureSelectionControl Table="RMPMCode" Label="RMPM Code">
<local:FeatureSelectionControl.SelectStatement>
select rarara
</local:FeatureSelectionControl.SelectStatement>
</local:FeatureSelectionControl>
etc etc etc
Each local:FeatureSelectionControl fetches a list of values from a database and lets the user choose one of more values.
I will need to use the same FeatureSelectionControls (i.e. with the same Table/Label/SelectStatement combination) in a dozen of dialog boxes. Since the SQL may change I don't want to duplicate the elements all over. So I thought I'd put them in an application resource. But first let's try with a window resource:
<Window.Resources>
<local:FeatureSelectionControl x:Key="GroupOwnerCRDSCode" Table="GroupOwnerCRDSCode" Label="Customer Group">
<local:FeatureSelectionControl.SelectStatement>
SELECT blablabla
</local:FeatureSelectionControl.SelectStatement>
</local:FeatureSelectionControl>
</Window.Resources>
Now how do I put the control in the StackPanel's collection of children ? IntelliSense didn't suggest a <staticresource> element but I still tried:
<ScrollViewer Grid.Row="2" HorizontalScrollBarVisibility="Auto">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<StaticResource ResourceKey="GroupOwnerCRDSCode" />
When I run it, I get a "first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll - Additional information: Stack empty.".
However, the preview in the Designer is just fine.
Does this approach has any chance of working ? What am I doing wrong ? If it works, will I get a single instance of a control (as identified by the same key) shared between my dialogs ? Or is a new instance created each time I pull from the resources ? What are the alternatives (I see one: put the three strings in resources, not the entire control).
|
|
|
|
|
Jean-Louis Leroy wrote: <layer>If it works, will I get a single instance of a control (as identified by the same key) shared between my dialogs ? Or is a new instance created each time I pull from the resources ?
Neither... Each defined resource is a single instance, but it gets defined once for every window. So each window gets exactly one instance. This means you can use it once per window, but no more than that (Because a UI element can only have one parent).
Jean-Louis Leroy wrote: When I run it, I get a "first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll - Additional information: Stack empty.".
I would suggest looking at the call stack, to get a little more information about that exception. Exactly what was it trying to do when it hit that exception? Was it related to the control being in the StackPanel, or was it something inside the FeatureSelectionControl?
Jean-Louis Leroy wrote: What are the alternatives (I see one: put the three strings in resources, not the entire control).
You could also do this by defining styles or templates. Those are intended to be reused (Unlike defining the control itself as a resource). Then, instead of putting a StaticResource directly into a StackPanel, you would do something like this:
<Style x:Key="GroupOwnerCRDSCode" TargetType="local:FeatureSelectionControl">
<Setter Property="Table" Value="GroupOwnerCRDSCode"/>
<Setter Property="Label" Value="Customer Group"/>
<Setter Property="SelectStatement">
<Setter.Value>
SELECT blablabla
</Setter.Value>
</Setter>
</Style>
<StackPanel ...>
<local:FeatureSelectionControl Style="{StaticResource GroupOwnerCRDSCode}"/>
</StackPanel>
|
|
|
|
|
Thanks for the very clear explanations and the suggestion about Styles. It looks like a better idea because - if I'm not mistaken - it will allow me to set other properties like Margin etc.
Out of curiosity I still took a look at the stack trace in my control-in-resource approach. Here it is:
PresentationFramework.dll!System.Windows.Markup.XamlParseException.ThrowException(string message, System.Exception innerException, int lineNumber, int linePosition, System.Uri baseUri, System.Windows.Markup.XamlObjectIds currentXamlObjectIds, System.Windows.Markup.XamlObjectIds contextXamlObjectIds, System.Type objectType) + 0x1bf bytes
PresentationFramework.dll!System.Windows.Markup.XamlParseException.ThrowException(System.Windows.Markup.ParserContext parserContext, int lineNumber, int linePosition, string message, System.Exception innerException) + 0x58 bytes
PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.ReadRecord(System.Windows.Markup.BamlRecord bamlRecord) + 0x75f bytes
PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.Read(bool singleRecord = false) + 0x1c bytes
PresentationFramework.dll!System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment() + 0xc9 bytes
PresentationFramework.dll!System.Windows.Markup.TreeBuilder.Parse() + 0xf bytes
PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, object parent, bool closeStream) + 0xc7 bytes
PresentationFramework.dll!System.Windows.Application.LoadComponent(object component, System.Uri resourceLocator) + 0x16e bytes
> CRRT.exe!CRRT.WindowCounterpartyGroupRiskReview.InitializeComponent() Line 1 + 0xb bytes C#
CRRT.exe!CRRT.WindowCounterpartyGroupRiskReview.WindowCounterpartyGroupRiskReview() Line 29 + 0x8 bytes C#
|
|
|
|
|
Ugh, typical unhelpful Xaml/Baml traces... Really wish Microsoft would put some useful information in there.
The only strategy I know for errors like that, is to just keep commenting out bits of the XAML until it runs successfully, and then narrowing it down from there.
|
|
|
|
|
Ian Shlasko wrote: Ugh, typical unhelpful Xaml/Baml traces... Really wish Microsoft would put some useful information in there.
Really wish Microsoft would give the source code like they used to for the CRT
I'm very happy with the Style-based solution, thanks.
|
|
|
|
|
|
What you need to do is override the HeaderTemplate for the top most items. Here's a hard coded version, that you should easily be able to extend to fit your own needs:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MenuSample.MainWindow"
x:Name="Window"
Title="Menu Window"
Width="640" Height="480">
<Window.Resources>
<DataTemplate x:Key="MenuHeader">
<StackPanel>
<Image Width="24" Height="24" Source="Images/favorites_24.png" Stretch="Fill"/>
<TextBlock Text="Outsource" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="0.106*"/>
<RowDefinition Height="0.894*"/>
</Grid.RowDefinitions>
<Menu HorizontalAlignment="Left">
<MenuItem HeaderTemplate="{DynamicResource MenuHeader}">
<MenuItem Header="Child 1" />
</MenuItem>
</Menu>
</Grid>
</Window>
|
|
|
|
|
Perfect. Thank you.
Everything makes sense in someone's mind
|
|
|
|
|
|
Ok, I don't think I understand this as well as I thought I did. Here's my code, which is just like yours:
<UserControl.Resources>
<DataTemplate x:Key="MenuHeader">
<StackPanel>
<Image Width="48" Height="48" Source="/Falcon;component/Media/Graphics/customer.png" Stretch="Uniform"/>
<TextBlock Text="Outsource" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
</Grid.RowDefinitions>
<Menu HorizontalAlignment="Left">
<MenuItem HeaderTemplate="{DynamicResource MenuHeader}">
<MenuItem Header="Child 1" />
</MenuItem>
<MenuItem HeaderTemplate="{DynamicResource MenuHeader}">
<MenuItem Header="Child 2" />
</MenuItem>
<MenuItem HeaderTemplate="{DynamicResource MenuHeader}">
<MenuItem Header="Child 2" />
</MenuItem>
</Menu>
</Grid>
The problem is, all 3 menu headers shares the same picture and caption. How can I assign them in the menu code?
Thanks
Everything makes sense in someone's mind
|
|
|
|
|
You're getting the same picture and caption because you are using a hardcoded header template here. What you need to do is use data binding, and specify the relevant header/image from code rather than in the XAML.
|
|
|
|
|
Has anybody gotten TaskbarItemProgressState.Indeterminate to work on .NET 4.0 / Windows 7? All the other states work fine, just TaskbarItemProgressState.Indeterminate doesn't do anything.
|
|
|
|
|
No, unfortunately. I'm trying this now, in the year 2019 with Windows 10 version 1809 and it isn't working correctly, as to my understanding. That is, when the TaskbarItemProgressState is set to Indeterminate , the Taskbar icon of the program turns a shade of green, but there is no scrolling marque.
I've tried in both WinForms and WPF. Also, with the Chrome web browser, when it downloads a file of unknown size (HTTP header Transfer-Encoding: chunked ), it used to give the scrolling marque, but now it does not. Instead, it's the same as what I'm getting in my test applications, it just turns a shade of green.
|
|
|
|
|
I have a style defined for a ListViewItem. In this style, there is a MultiDataTrigger. One of the conditions uses RelativeSource to get to a property in the ListView (RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}).
The trigger is working correctly, just as I expect, so I know all the syntax and everything is defined correctly.
HOWEVER, when you scroll a ListView and the ListViewItem goes off screen, it gets removed from the visual tree. This results in a lot of errors:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='ListView', AncestorLevel='1''. BindingExpression:Path=SomeDP; DataItem=null; target element is 'ListViewItem' (Name=''); target property is 'NoTarget' (type 'Object')
I've tried everything I know of to get rid of them:
1) Tried adding a FallbackValue to the binding. This solves the error messages on XP, but does not work on Windows 7??? .NET 4.0 on both OSes.
2) Tried running the value through a dummy converter. This has gotten rid of error messages in the past, but not this time.
3) Tried setting the PresentationTraceSources.TraceLevel="None" AP on the condition. No effect.
Any other way to solve this?
|
|
|
|
|
I believe that a ListView uses a VirtualizingStackPanel for it's ItemsPanel and that the IsVirtualizing property defaults to true. Try setting it to false if you don't need your listview to hold many items. Either that or try using a regular StackPanel for the ItemsPanel.
while (e) { Coyote(); }
|
|
|
|
|
Definitely don't want to turn off virtualization. That eats a lot of memory. If I have 200 items, it adds around 50MB.
|
|
|
|
|
Hello!
i have a problem with the resource dictionaries in silverlight,
control styles is using the colors in my colors resource.
but when i do this i get runtime error when i load the silverlight app in my browser:
Cannot find a Resource with the Name/Key OfficeBlue [Line: 10 Position: 44]
i have confirmed that the key name exists in colors.xaml
this is from my app.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml" />
<ResourceDictionary Source="Navigate/Control styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
How do i use colors.xaml resource in my control style?
Thanks!
modified on Tuesday, April 19, 2011 2:25 AM
|
|
|
|
|
It is unable to find the Resource file. Give a proper path there. A typical resource dictionary path will look as below:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ASSEMBLY_NAME;component/FILENAME.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Note: Change the name of the ASSEMBLY_NAME in the above code. Also change the FILENAME. If it is in a different sub directory, say "Themes", it will look as below:
<ResourceDictionary Source="/ASSEMBLY_NAME;component/Themes/FILENAME.xaml"/>
Hope this will answer your query. Mark as Answer, if this helps.
Regards - Kunal Chowdhury | Microsoft MVP (Silverlight) | CodeProject MVP | Software Engineer
|
|
|
|