tags:

views:

55

answers:

2

I have a ParentViewModel which has ObservableCollection named Notices.

public class Notice
    {

        public string Content { get; set; }

        public NoticeType Type { get; set; }

    }

I have static controls at user control where I want to bind this observablecollection to this static controls. And I don't know how binding this Notices depending of its Types. I want bind notice with Type FirstType to "first row" and notice with Type SecondType to "second row" Also If user check checkbox Notice should be removed from collection.

There are my codes

<UserControl x:Class="Repo.UserControlNotices"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="Auto" Width="Auto">
    <Grid DataContext="{Binding}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
 </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>

        </Grid.ColumnDefinitions>
    <TextBox Text="FirtNotice" >


     </TextBox>
<StackPanel Grid.Row="0" Grid.Column="1">
            <TextBox Text="{Binding Path =Content}" >
            </TextBox>
            <CheckBox >
            </CheckBox>
        </StackPanel>
        <TextBox Grid.Row="1" Text="SecondNotice">
        </TextBox>
        <StackPanel Grid.Row="1" Grid.Column="1">
            <TextBox Text="{Binding Path =Content}" >
            </TextBox>
            <CheckBox >
            </CheckBox>
        </StackPanel>
    </Grid>
</UserControl>


class ParentViewModel
{

    public ObservableCollection<Notice> Notices { get; set; }


    public ParentViewModel()
    {

        ObservableCollection<Notice> loadedNotices = new ObservableCollection<Notice>();


      loadedNotices.Add(new Notice() { Content = "Something", Type = NoticeType.FirstType });
loadedNotices.Add(new Notice() { Content = "Something", Type = NoticeType.SecondType });
            Notices = loadedNotices;
        }
    }

<Window x:Class="Repo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Repo="clr-namespace:Repo" Title="Window1" Height="300" Width="300">
    <Window.Resources>

        <Repo:ParentViewModel x:Key="parentVM"/>

    </Window.Resources>

    <Window.DataContext>
        <StaticResourceExtension ResourceKey="parentVM"/>
    </Window.DataContext>
    <Grid>

                            <Repo:UserControlNotices DataContext="{Binding Path=Notices}">

                            </Repo:UserControlNotices>

    </Grid>
</Window>

This is example in winforms: alt text

A: 

I'm not exactly sure what your asking but I think you most likely need to use the IValueConverter interface. You declare a new class implementing the IValueConverter interface and implement the Convert and ConvertBack methods like so

public Converter implements IValueConverter{
      Object Convert(value, targetType, parameter, culture){
            // 'value' has the bound value from the xaml
            // do some converting and return the result
      }
      Object Convert(value, targetType, parameter, culture){
            // you can figure this one out, usually used for a two-way relationship
      }

}

In the xaml, you need a ResourceDictionary in your xaml with something like

xmlns:y="clr-namespace:NamespaceWithClass">
<y:Converter x:Key="someName" />

And reference this converter in your controls

<TextBox Text="{Binding Content, Converter={StaticResource someName}}" >           
            </TextBox>  

Not sure if this is exactly what your looking for but I hope it helps.

PhilBrown
A: 

Is it not easier to just have two properties on ParentViewModel, e.g.,...

public static IEnumerable<Notice> FirstTypeNotices
{
    get
    {
        return Notices.Where(n => n.Type == NoticeType.FirstType);
    }
}

...and bind to those?

You'll probably have to hook up to the Notices.CollectionChanged event and raise PropertyChanged events for each of the two properties.

IanR
If doing that, I suspect you'd also need to put a .ToList() on the end of your Where. Otherwise, the binding might ignore the PropertyChanged on grounds that the *expression* you're returning hasn't changed. At least, I've had plenty of such binding problems that have come down to that in the past.
Mal Ross