Showing posts with label WPF Forum Questions. Show all posts
Showing posts with label WPF Forum Questions. Show all posts

Tuesday, June 02, 2009

WPF Databinding : Using CompositeCollection

The goal is to have a ComboBox whose ItemsSource should bind to more than one collection. In order to this, we make use of CompositeCollection as shown below.

XAML

<StackPanel>
<ComboBox Name="cb" ItemsSource="{Binding MoreThanOneCollection}">
</ComboBox>
</StackPanel>



Code-behind




Private _moreThanOneCollection As New CompositeCollection

Public Property MoreThanOneCollection() As CompositeCollection
Get
Return _moreThanOneCollection
End Get
Set(ByVal value As CompositeCollection)
_moreThanOneCollection = value
End Set
End Property

Private Sub Window_Loaded(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs)
Me.DataContext = Me 'set the datacontext
BindData()
BindMoreData()
End Sub


Sub BindMoreData()
Dim data2 As New CollectionContainer
data2.Collection = GetData().Reverse()
'another set of data, just for the heck of it
MoreThanOneCollection.Insert(0, data2)
End Sub


Sub BindData()
Dim container = New CollectionContainer
container.Collection = GetData() ' the first data
MoreThanOneCollection.Add(container)
End Sub

Function GetData() As IEnumerable(Of String)
Dim x As New ObservableCollection(Of String)
x.Add("Item 1")
x.Add("Item 2")
x.Add("Item 3")
Return x
End Function


Just for practise purpose, I thought I would create the composite collection in code. This can also be done in XAML.

Loading BitmapImage from disk

While loading image in XAML is pretty easy (use <Image Source="xx.jpg"/>), it is not so straight forward to load an ImageSource from a file. (I always forget how to do this). So here is the code which might help you all. I have also specified some commented code which can be used to get thumbnails out of the image and other options like caching, etc.

ImageSource LoadImage(string filePath)
{
BitmapImage img = new BitmapImage();
try
{

img.BeginInit();
img.UriSource = new Uri(filePath, UriKind.RelativeOrAbsolute);
img.CacheOption = BitmapCacheOption.OnLoad;
//img.CreateOptions = BitmapCreateOptions.DelayCreation;
img.DecodePixelWidth = 50;
//img.DecodePixelHeight = 200;
img.EndInit();
}

catch
{
}
return img;

}

By the way, I have at last set up SyntaxHighlighter for my blog! this is sweet. Thanks to this post for the instructions.

Monday, June 01, 2009

ListView/ListBox Selected Item Color – Active and Out of Focus

The following snippet of XAML can help you set a fixed color scheme for a selected item in the list controls whether the control has focus or not.

   1: <StackPanel Orientation="Vertical">


   2:         <ListView Background="SeaGreen">


   3:           <ListView.Resources>                        


   4:             <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>


   5:             <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}">            


   6:                   Red


   7:             </SolidColorBrush>


   8:             <Style TargetType="{x:Type ListViewItem}">


   9:               <Style.Triggers>


  10:                 <Trigger Property="IsSelected" Value="True">


  11:                   <Setter Property="Foreground" Value="Black"/>


  12:                 </Trigger>


  13:               </Style.Triggers>


  14:             </Style>


  15:           </ListView.Resources>


  16:             <ListViewItem>String 1</ListViewItem>


  17:             <ListViewItem>String 2</ListViewItem>


  18:             <ListViewItem>String 3</ListViewItem>


  19:         </ListView>


  20:         <Button>Button 1</Button>


  21:     </StackPanel>


Friday, October 03, 2008

MSDN Question on WPF: Refreshing Data Bound Items

A poster on MSDN Forums asked a question about data binding. I had the same issue later when I was working on my query base editing tool. The question goes something like this

There are two textboxes A, B and C. TextBox A and B are bound to some data source. TextBox C has value which is bound to a converter which sends the value based on the content inside A and B. The first time the form shows up, C looks fine. Now, I go ahead and edit the text in one of the A or B. The C does not get updated until I reload the section(form). C is basically data bound to A and B. So how do I update the databound value on C?

The question or scenario is not exactly as described above, but I hope it is simple enough to give a clear picture.

Let me try and explain what happens.

When the form is loaded, the data bound controls are updated. Then the changes made are not reflected onto the C, but the actual source is updated. So we need to add some framework that updates even C.

The Binding element has a property called "NotifyOnSourceUpdated". If you set this value on Binding to True and then handle the SourceUpdated event on that data bound element, you can track the changes made from the control. Doing so, we can then refresh the data binding on C. The Xaml for A, B and C can look something like this:

<
StackPanel DataContext={Binding MyStupidDataSource}>


<TextBox Name="A" Text={Binding TextAValue,NotifyOnSourceChanged=True}"
SourceUpdated="
RefreshContentsOfC"/>


<TextBox Name="B" Text={Binding TextBValue,NotifyOnSourceChanged=True}"
SourceUpdated="
RefreshContentsOfC"/>


<TextBox Name="C" Text={Binding Coverter=MyStupidConverter}"/>


</StackPanel>

Notice the NotifySourceChanged and SourceUpdated sections in the above XAML.
Now the RefreshContentsOfC is an event handler which refreshes the data binding on C. The code would look like.

public void RefreshContentsOfC(object sender, DataTransferEventArgs e){

//Refresh Data Binding -> Answer for the question

BindingOperations.GetBindingExpressionBase(C, TextBox.TextProperty).UpdateTarget();

}

Wednesday, October 01, 2008

MSDN Question on WPF: Label inside a Gridcolumn should determine the width of the column.

Given XAML.

<
Grid
>
    <
Grid.ColumnDefinitions
>
        <
ColumnDefinition
/>
        <
ColumnDefinition
/>
        <
ColumnDefinition
/>
        <
ColumnDefinition
/>
    </
Grid.ColumnDefinitions
>
    <
Grid.RowDefinitions
>
        <
RowDefinition
/>
    </
Grid.RowDefinitions
>
    <
Label Grid.Column="0" MinWidth="120" Width="200">Some caption</Label
>
    <
TextBox Grid.Column
="1" />
    <
Label Grid.Column="2" MinWidth="120" Width="200">Some other caption</Label
>
    <
TextBox Grid.Column
="3" />
</
Grid
> 

Rendering the xaml as it is in a XAML viewer like KaXaml or XamlPad or Visual Studio Xaml editor, shows that the labels get clipped if the text is too big. So how do you make the label text size determine the width of the column?

For this question, I have referred to Programming WPF by Chris Sells and updated my knowledge about Grid layout in WPF. Essentially, the Width of a column in a grid can be fixed (do not use unless you really want to), automatic and proportional(use "*"). So when a column takes * as width, it takes the space that is left after the fixed and auto width columns are rendered. So if you modify the above XAML with the information I just gave, it works out fine.

The modified XAML would be.

<
Grid
>
    <
Grid.ColumnDefinitions
>
        <
ColumnDefinition Width
="Auto"/>
        <
ColumnDefinition Width
="*"/>
        <
ColumnDefinition Width
="Auto"/>
        <
ColumnDefinition Width
="*"/>
    </
Grid.ColumnDefinitions
>
    <
Grid.RowDefinitions
>
        <
RowDefinition
/>
    </
Grid.RowDefinitions
>
    <
Label Grid.Column="0">Windows Presentation Foundation, Silverlight, Windows Communication Foundation, Windows Workflow Foundation</Label
>
    <
TextBox Grid.Column
="1" />
    <
Label Grid.Column="2">another long caption in here</Label
>
    <
TextBox Grid.Column
="3" />
</
Grid>

As you can see, I have just altered the Width property cleverly(theoretically, from the book) such that the label columns have width auto and the other labels have width *. So the columns whose width is Auto is rendered first and then the columns with proportionate width are rendered.

I like this little things on forums which gives us a lot of information. So, if you want to become a better developer you should:
1. Read Blogs, Write Blogs
2. Try and answer forum questions.

MSDN Question on WPF : Display Image XAML without copy/paste

As a part of personal development, I have once again started answering questions on forums. I was once a top contributor at dotnetforums.com but the site is no longer up. From what I learnt back then, I strongly believe that you get to learn more by answering people's questions online. As a part of it, I decided I would write a little about every answer that I give on windowsclient.net, if it is marked as answer. So, here comes the first post. One member had company logo exported as XAML. Now he wants the logo to show up inside an Image element, without having to paste the XAMl at all the places.

Question: Is there a way to display the contents of this file inside an <Image> element, therefore without copying/pasting the file content?

My suggestion (definitely not perfect):
Give the Image a name. Modify the XAML you got into a drawing image root and save it as a resource. Load the XAML at runtime from the resource and use XamlReader.Load("your xaml"). It now returns DrawingImage and set it to the source of the actual image. So, it would look something like this.

DrawingImage img = XamlReader.Load("mylogo.xaml") as DrawingImage;

Set this "img" as Source for the Image element.

where mylogo.xaml would be like:

<DrawingImage xmlns="wpf namespace...">

<!-- Xaml for your image, that fits in as a child for DrawingImage -->

</DrawingImage>