|
Did you mean to write a value converter that takes some input(s) and returns an ImageSource object? Something like:
<Image Source="{Binding ..., Converter={StaticResource ...}" ... />
Ok, well, that won't accomplish what I'm looking for. I did that yesterday and it did work, but with issues. I used reflection in the converter to obtain the value of object.<Path> and I did get the image to show up, but this is resulting in a one time binding. If the value of object.<Path> changes, it wouldn't be reflected in the UI and I need it to be. If an app changes object.ImageSource, the icon should change on the screen obviously.
I also tried setting the binding on Image.Source within the converter, but that just confused WPF and the binding engine crashed .
Unless you had some other thought?
|
|
|
|
|
Does the value of object Path raise a change notification. If it doesn't then there's not a lot you can do to updated the binding anyway. If it does, then you could use the Reactive Extensions to watch that property, and react accordingly. This could not, of course, be done in the converter - which is there purely to convert the object. You would need to do this in the VM which backs your view, and then you could react to the changes there. Thinking about it, this is the simplest way to achieve this.
|
|
|
|
|
Well, this is for a custom control (an enhanced ListView control), so there is no View / ViewModel involved. It is still a lookless control of course . I'm just not tying the design of the control to MVVM. Yes, the underlying property in the test app / test object does implement INPC.
Anyways, I dumped the Converter idea and went a different route which is working how I want it.
The "ListViewEx" overrides the item container generation and creates ListViewItemEx objects instead of ListViewItem objects.
Then in ListViewItemEx.OnApplyTemplate() I find the image control in the data template and create a Binding object and call image.SetBinding(Image.Source, binding);
This way I get true data binding to the underlying property and I don't have to do any crazy voodoo magic to get stuff to refresh. Of course, there is one issue and that is if the user suddenly decides to change Path from "ImageSource" to "SomethingElse", its not going to work because OnApplyTemplate() only gets called once.
EDIT: Actually, I guess there is a work-around. ListViewItems are regenerated when they go off screen and come back on, so I guess the user could just refresh the view if they really want to change Path.
|
|
|
|
|
Without knowing what effect the ListView is having, I have to wonder whether or not you could have achieved the same functionality with an attached behavior. Whenever I hear that a WPF item has had to be subclassed, I end up wondering if the wrong problem has been solved.
|
|
|
|
|
My "ListViewEx" adds back all the missing functionality in the stock ListView (built in sorting w/ native OS look & feel, filtering, real OS style multi-select w/ translucent rectangle, keyboard interface, etc). I'm trying to structure my public interface so that it looks like a "factory install" and will work with MVVM and is completely generic and independent of anything. The particular feature I was adding was item image support. Following the model already in place in WPF, I made it similiar to DisplayMemberPath where you give the name of the property that will provide the ImageSource. The property I added was added to "GridViewEx" since that is where it belongs. The Image control itself however is in the ListViewItem data template.
I don't know how closely you've worked with ListView internals, but its quite an annoying control. It has lots of levels of objects and lots of templates. The column headers are actually split into 2 separate classes, etc.!
There are plenty of valid reasons you need to subclass a WPF item. Sometimes part of the template or behavior you need to modify belongs to the item.
For example, try adding back the node lines in a TreeView without subclassing the TreeViewItem .
|
|
|
|
|
Indeed. As I said, I didn't know your requirements, and in this case what you have had to do is legitimate. Saying that, I have seen far more cases where people have subclassed to achieve something rather than using attached properties and behaviours which are more in keeping with the WPF of doing things.
|
|
|
|
|
Hi,
I have a DataGrid that is bound to ObservableCollection.I have textbox control in the same window..Based on text change event of text box(let us say filtering..based on typed character datagrid should change) how do i update the grid in MVVM model?
|
|
|
|
|
The glib response is change the observable collection the grid is bound to. Need a bit more info really.
|
|
|
|
|
Have a look at this[^] post for some ideas.
|
|
|
|
|
Hello ,
I am manoj.
As these days i was working with WPF canvas and i find difficulties in resizing my controls while resizing the windows form
Like
1. I have few controls on my canvas at diff diff location
2. when i resize the controls the approrpiate controls i mean childs should be resized
3. like width,height,left,top,bottom,right
as more brief
I placed four controls on four corners of canvas
now if i resize the canvas i should be able to resize the child controls & even the Left,top,bottom ,right should be same
I mean if one controls is at left=0,Top=0
it should be there itself
if it is at the right end corner then even i resize the canvas the controls should resize but the right should be zero.
How can i achieve this ?
Please
Thanks,
Manoj
Thanks,
Manoj
|
|
|
|
|
This[^] custom control might help.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
|
|
|
|
|
Try setting the margin property of the control. It takes a little playing around with but it should do what you are after.
"You get that on the big jobs."
|
|
|
|
|
1.
I need to change each input character in autocompletebox to Uppercase.
For a textbox I am using this -
private void acb1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
char ch = Convert.ToChar(e.Text);
if (char.IsLetter(ch))
{
acb1.Text += Char.ToUpper(ch);
e.Handled = true;
}
}
This works too for autocomplete box but this disables the dropdown list to show. Anyway around this?
2.
I need the text input to match only listbox items. If the user inputs a char so that the text has no matches, I need to delete that char back.
I can do this manually but since this will give an empty dropdown menu, I think there is an easier way.
3.
When entering text and the dropdown menu show up, I need the first item to be highlighted so that the user can just press Enter to select.
Thanks in advance.
|
|
|
|
|
To set the characters to upper case, set CharacterCasing.Upper on the textbox.
|
|
|
|
|
I am using the AutoCompleteBox from the WPF toolkit. This does not seem to have the CharacterCasing property.
|
|
|
|
|
You could have passed that vital nugget of information originally. When you post questions, you should give all the pertinent facts as we can't guess what you are using. Bear in mind that the WPF control is made up of constituent parts, what you need to do is find the templated part PART_EditableTextbox, and apply the character casing here. To do this, use something like this:
myComboBox.Template.FindName("PART_EditableTextbox", myComboBox) as TextBox;
|
|
|
|
|
Lol I tought the title said enough
Thanks for the tip but can you please give more code how to do it. I'm still trying to make ends meet with WPF.
|
|
|
|
|
Moonwalker031 wrote: I tought the title said enough
You thought wrong.
Moonwalker031 wrote: can you please give more code how to do it
Well, I gave you the code to find the template part. How hard can it be adding the CharacterCasing - I did the hard part for you.
Show me what code you've attempted.
|
|
|
|
|
Umm I told you I'm a beginner. I tried the following but got an Exception
TextBox txt;
txt = acb1.Template.FindName("PART_EditableTextbox", acb1) as TextBox;
txt.CharacterCasing = CharacterCasing.Upper;
I have not grasped what the Template.FindName is returning exactly.
|
|
|
|
|
1) you didn't bother to tell us what the exception was
2) I'm assuming the exception is because
a) AutoCompleteBox didn't name the part "PART_EditableTextbox"
OR
b) You called FindName too early (like in the constructor). What Pete didn't bother to tell you is that searching for a part through the template is only valid AFTER the template has been applied. Typically you would override OnApplyTemplate() (calling the base class first of course) and then do the above code.
Or why not modify the XAML directly? That would be the prefered solution if you are always going to want it upper case.
|
|
|
|
|
NullReference Exception - Object reference not set to an instance of an object.
I am calling the findname in the middle of the prog after the user has entered some parameters (in other textboxes).
Will try to modify the XML if I figure out the syntax.
|
|
|
|
|
my:AutoCompleteBox Style="{StaticResource acbStyle}" TextBoxStyle="{StaticResource acbTxtStyle}"
I managed to set the Casing to Upper in XAML by setting a textBox Style with Casing = Upper and the code above.
Thanks for the help as this is much simpler.
However I need to use the code method too. I need to move the cursor to the left or right depending on the input characters. Since Autocomplete box does not have a SelectionStart property I need to use the TextBox template again.
So can someone reply why I am getting a NullReference Exception when I use the code posted earlier?
|
|
|
|
|
Update -
Managed to fix all problems finally. The null Exception was showing because the property is named "Text" and not "PART_EditableTextBox" in AutocompleteBox. Thanks again.
One last question.
I am using the Populated Event to check if there are any items in the dropdown list. The list is given through PopulatedEventArgs with the Data property. Since this is IEnumerable type, what is the easiest way to check if the list is empty or not?
I worked around it be copying the data to a listbox and then checking the items count of the listbox. But this is not the best way for sure.
|
|
|
|
|
Using RowDetailsTemplate might be useful to implement nested datagrids.
For example, your normal datagrid might look like this.
<data:DataGrid Name="ParentDG" AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="<<ColumnInfo>>" Binding="{Binding <<BindingInfo>>}" IsReadOnly="True" />
...
</data:DataGrid.Columns>
<data:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<data:DataGrid Name="NestedDG"></data:DataGrid>
</StackPanel>
</DataTemplate>
</data:DataGrid.RowDetailsTemplate>
</data:DataGrid>
Note that the RowDetailsVisibilityMode is set to "VisibleWhenSelected". Thus, whenever you click on a row in the datagrid, the content of rowdetailstemplate is displayed.
The only plumbing left now is to set the datasource of the inner-grid. You can do that by following these steps:
1. Create an event handler for "RowDetailsVisibilityChanged" event
ParentDG.RowDetailsVisibilityChanged += new EventHandler<datagridrowdetailseventargs>(ParentDG_RowDetailsVisibilityChanged);
2. Define the event handler to set the data-source for the inner-grid.
void ParentDG_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
DataGrid nestedGrid = (DataGrid)e.DetailsElement.FindName("NestedDG");
if (e.Row.DetailsVisibility == Visibility.Visible)
{
nestedGrid.ItemsSource = <<Set the item source for the nested grid here>>;
}
}
Note that we obtian the nested grid from the DetailsElement and set the item source for the nested datagrid.
SOURCE : By implementation in my project and also Silverlight Official Forum
|
|
|
|
|
Thank you for posting this, but as you've posted this in a Q and A forum, there will come a point where this disappears from the front page. A better approach would be for you to convert this into a Tip/Trick here on the site.
|
|
|
|