Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

WPF MVVM pattern

i am doing a simple project with mvvm pattern. its about one list that every row has one textbox and delete button and at

buttom we have one text box and add button like this:

name1 buttondelete

name2 buttondelete

name3 buttondelete

.

.

textbox buttonadd

with click the buttondelete the row should delete and with click bottonadd the text of textbox should insert in list as new

row.

i have three layer Sepand.WPFProject.Model , Sepand.WPFProject.ViewModel , Sepand.WPFProject.View;

in model i have context and repository and model (here my model is Category that have Name & ID property) class. repository is like this:

    public class ModelRepository<T>
    where T : class
{
    ModelDbContext ctx = new ModelDbContext();
    public IQueryable<T> GetAll()
    {
        IQueryable<T> query = ctx.Set<T>();
        return query;
    }

    public void Add(T entity)
    {
        ctx.Set<T>().Add(entity);
        ctx.SaveChanges();
    }

    public void Delete(T entity)
    {
        ctx.Set<T>().Remove(entity);
        ctx.SaveChanges();
    }

in viewModel i have categoryViewModel class like this:

    public class CategoryViewModel    
{
    ModelRepository<Category> repository = new ModelRepository<Category>();
    ObservableCollection<Category> categories = new ObservableCollection<Category>();
    Category category = new Category();

    public ObservableCollection<Category> GetAll()
    {
        IQueryable<Category> categoryRepository = repository.GetAll();

        foreach (Category Category in categoryRepository)
            categories.Add(Category);
        return categories;
    }

    public ObservableCollection<Category> GetAllCategories
    {
        get { return GetAll(); }
    }
     public string TxtName
    {
        get { return category.Name; }
        set { category.Name = value; }
    }

in View in code behind i have

this.DataContext = new CategoryViewModel();

and in XAML i have

    <Window.Resources>
    <DataTemplate x:Key="CategoryTemplate">
        <Border Width="400" Margin="5" BorderThickness="1" BorderBrush="SteelBlue" CornerRadius="4">

            <StackPanel Grid.Row="0" Orientation="Horizontal">
                <TextBlock Width="300" Margin="5" Text="{Binding Path=Name}"></TextBlock>
                <Button Name="btnDeleteCategory" Width="50" Margin="5" Click="btnDeleteCategory_Click" >-</Button>
            </StackPanel>

        </Border>
    </DataTemplate>
</Window.Resources>

.

.

            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <ListBox Grid.Column="0"  Grid.Row="0" Name="lstCategory" ItemTemplate="{StaticResource CategoryTemplate}" ItemsSource="{Binding Path=GetAllCategories}"/>
                <StackPanel Margin="5" Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
                    <Label Content="Name : "/>
                    <TextBox Name="TxtName" Text="{Binding Path=TxtName ,Mode=TwoWay}" Width="260"/>
                    <Label Width="50"/>
                    <Button Width="50" Content="+" Name="btnAddCategory" Click="AddCategory_Click" />
                </StackPanel>

</Grid>

</Grid>

and now when i run app the listbox populated with data from database; but i could not write code for addbutton and

delete button;

could anyone tell me what should i do?

and why i could not bind the text of textbox in list to TxtName Property of CategoryViewModel class ?

i mean here

                <TextBlock Width="300" Margin="5" Text="{Binding Path=Name}"></TextBlock>

when i write Binding Path=TxtName the list box would not show data but with Binding Path=Name

it shows data from database

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your question is a bit scattered. But I'll try address what I think are your issues.

You say in the code behind you have:

this.DataContext = new CategoryViewModel();

But nothing else.

First thing to do with checking why your button isn't working would be to see what action it is performing. Your XAML states it's using a click event:

btnDeleteCategory_Click

Where's that? Is it not in your code-behind too? It might be that you've not got anything and that's why your button isn't doing anything - you've not instructed it to do anything!

In MVVM you should be binding your button using Commands in your ViewModel, similarly to how you bind data to Properties in your ViewModel.

You need something like:

Command="{Binding Path=DeleteCommand}"

in your view, and:

public ICommand DeleteCommand
{
    get { return new DelegateCommand<object>(FuncToCall, FuncToEvaluate); }
}

private void FuncToCall(object context)
{
    //this is called when the button is clicked - Delete something
}

private bool FuncToEvaluate(object context)
{
    //this is called to evaluate whether FuncToCall can be called
    //for example you can return true or false based on some validation logic
    return true;
}

Binding to TxtName might not be working because it does not implement/call PropertyChanged.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...