Pergunta

I'm using Elysium framework to use the ApplicationBar control, and I want to make its CommandButton dynamic for my Views. So, I'm binding its ItemsSource property to an ObservableCollection<CommandButton> and each view will create its own actions.

Before using Elysium I had this button:

<Button>
    <Canvas Width="60" Height="60" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
        <Path Width="27.854" Height="31.076" Canvas.Top="14" Fill="White" 
              Data="F1 M 51.5487,37.9814L 56.814,41.0534L 50.3383,48.7636L 50.3383,48.8841L 60.0205,46.9565L 60.0205,53.0403L 50.2777,51.414L 50.2777,51.5344L 56.814,59.0037L 51.4882,62.0757L 47.978,52.7994L 47.8569,52.7994L 44.4072,62.0757L 39.2025,59.0037L 45.6782,51.4742L 45.6177,51.3537L 36.1159,53.0403L 36.1159,46.9565L 45.5571,48.8841L 45.5571,48.7636L 39.2025,41.1137L 44.5888,37.9814L 47.9174,47.3179L 48.0385,47.3179L 51.5487,37.9814 Z M 20,17L 43.25,17L 56,29.75L 56,39L 52,36.75L 52,34L 39,34L 39,21L 24,21L 24,55L 41,55L 37.5,59L 20,59L 20,17 Z M 43,22.25L 43,30L 50.75,30L 43,22.25 Z " Canvas.Left="17.24" Stretch="Fill"/>
    </Canvas>
</Button>

and this is how I'm creating an action on my View.

CommandButtonList.Add(new CommandButton
{
    Header = "new version"
});

I would like to know if it's possible to create the <Canvas> programmatically? If it's, so how?

Just remember that I'm using MVVM

Edit:

Each action will have a different <Canvas> and <Path>

Foi útil?

Solução

If you're storing a collection of CommandButton, which is a UiElement, in your ViewModel to bind to then you're already breaking one of the main "rules" of MVVM: no View in the ViewModel. If you want to really go the MVVM route, change your collection to some data type and then handle the setup of the UI controls (CommandButton, Canvas, etc.) in XAML with DataTemplates. If you want to stick with your current direction then you might as well just create and assign the Canvas right there with the CommandButton creation.

What your collection data items look like all depends on what needs to be set differently on each button. If you think about creating a set of buttons manually, every property that's different across each one should be bound to a field on the data item for that button. Data can be as simple as a collection of strings. This could be used for a different raster image on each button (lots of different options for locations):

CommandButtonList = new ObservableCollection<string>
{
    "http://foo.com/image1.jpg",
    @"c:\images\image2.jpg",
    "/ProjectImages/image3.jpg"
};

Then your ItemsControl that binds to it would set its ItemTemplate to something like this:

<DataTemplate>
    <Button>
        <Image Source="{Binding}"/>
    </Button>
</DataTemplate>

Where the binding now uses the strings from the collection. This is obviously a simple example and there's lots of additional variation you can do: more complex data objects with lots of properties, more complex template with lots of bindings, multiple data templates on the same ItemsControl by either template DataType or a TemplateSelector, etc.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top