WPF绑定到ViewModel中的模型属性[MVVM]

时间:2017-09-06 06:54:55

标签: c# wpf

我在我的应用程序中使用多种语言 我试图用MVVM模式做这个,这对我来说是新的,所以 我从CodeProject和Tutorialspoint阅读了教程。

继承我的项目结构:

Model
 ConverterModel.cs
 LanguageModel.cs
ViewModel
 ConverterViewModel.cs
View
 ConverterView.xaml
  ConverterView.xaml.cs
MainWindow.xaml
 MainWindow.xaml.cs

我为我需要的所有语言字符串创建了一个模型:

internal class LanguageModel : INotifyPropertyChanged
{
    //GUI Language

    private string title;
    private string inputBtn;
    private string outputBtn;
    private string convertBtn;
    ...
    public string Title
    {
        get
        {
            return title;
        }

        set
        {
            if(title != value)
            {
                title = value;
                RaisePropertyChanged("Title");
            }

        }
    }


    public string InputBtn
    {
        get
        {
            return inputBtn;
        }

        set
        {
            if (inputBtn != value)
            {
                inputBtn = value;
                RaisePropertyChanged("InputBtn");
            }
        }
    }

    public string OutputBtn
    {
        get
        {
            return outputBtn;
        }

        set
        {
            if (outputBtn != value)
            {
                outputBtn = value;
                RaisePropertyChanged("OutputBtn");
            }
        }
    }

    public string ConvertBtn
    {
        get
        {
            return convertBtn;
        }

        set
        {
            if (convertBtn != value)
            {
                convertBtn = value;
                RaisePropertyChanged("ConvertBtn");
            }
        }
    }

   ...

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        if(PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

}

然后我在我的ViewModel中创建该模型的一个实例,并用所需的数据填充它:

 internal class ConverterViewModel 
{
    internal Settings Settings{ get; set; }
    ConverterModel Model { get; set; } //where the Data Fill Method is located 
    internal LanguageModel LanguageModel { get; set; }
    String Title {get; set;} = "Banana"; //<-- this seems to work just fine

    internal ConverterViewModel()
    {
        Model = new ConverterModel();
        Settings = new Settings();
        if(Settings.Language == "")
        {
            Settings.Language = "English";
            //getLanguage
            Settings.Save();
        }
        this.LanguageModel = Model.SetLanguageModel(Settings.Language);
    }

ConverterModel中的数据填充方法:

class ConverterModel
{
            internal LanguageModel SetLanguageModel(string language)
    {
        switch (language)
        {
            case "English":
                LanguageModel english = new LanguageModel()
                {
                    Title = "TitleSomething",
                    InputBtn = "Inputfile",
                    OutputBtn = "Outputfile",
                    ConvertBtn = "Convert",
                };
                return english;
            case "German":
                LanguageModel german = new LanguageModel()
                {
                    //Work in Progress
                };
                return german;
            case "French":
                LanguageModel french = new LanguageModel()
                {
                    //Work in Progress
                };
                return french;
            case "Italian":
                LanguageModel italian = new LanguageModel()
                {
                 //Work in Progress
                };
                return italian;
            default: return null;
        }

    }
}

我的Bindings设置如下。

MainWindow:

<Window x:Class="dta2pain.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:dta2pain"
    xmlns:view="clr-namespace:dta2pain.View"
    xmlns:viewModel="clr-namespace:dta2pain.ViewModel"
    mc:Ignorable="d"
    ResizeMode="NoResize"
    WindowStartupLocation="CenterScreen"
    Title="{Binding Title}" //<-- works
    Height="657" Width="910">
<Grid>
<Window.DataContext>
    <viewModel:ConverterViewModel/>
</Window.DataContext>
    <view:ConverterView x:Name="ConverterViewControl">
        <view:ConverterView.DataContext>
            <viewModel:ConverterViewModel/>
        </view:ConverterView.DataContext>
    </view:ConverterView>
</Grid>

ConverterView:

<UserControl x:Class="dta2pain.View.ConverterView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:dta2pain.View"
         xmlns:viewModel="clr-namespace:dta2pain.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="657" d:DesignWidth="910"
         Title = "{Binding Path = Title}">
<Grid>
    <Menu HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="910" >

    </Menu>
    <Grid Margin="0,15,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.5*" />
            <RowDefinition Height="1*"/>
            <RowDefinition Height="0.75*"/>
            <RowDefinition Height="1.5*"/>
            <RowDefinition Height="0.25*"/>
        </Grid.RowDefinitions>
        <Image x:Name="LogoImg" Grid.Row="0" Source="../Images/mammutLogoTop1280.jpg" Margin="0"/>

        <Grid Grid.Row="1" Margin="15,5,15,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1.5*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="765*"/>
                <ColumnDefinition Width="62*"/>
                <ColumnDefinition Width="47*"/>
            </Grid.ColumnDefinitions>
            <TextBox x:Name="InputTxt" Template="{StaticResource TextBoxBaseControlTemplate}" Grid.Column="0" Grid.Row="0" Margin="0,0,5,0" Height="30" FontSize="14" VerticalContentAlignment="Center" />
            <Button x:Name="InputBtn" Template="{StaticResource RoundCornerBtn}" Grid.Column="1" Grid.Row="0" Margin="5,0,0,0" Height="30" FontSize="14" Background="#FF006561" Foreground="White"  Grid.ColumnSpan="2" Content="{Binding LanguageModel.InputBtn}"/>
            <TextBox x:Name="OutputTxt" Template="{StaticResource TextBoxBaseControlTemplate}" Grid.Column="0" Grid.Row="1" Margin="0,0,5,0" Height="30" FontSize="14" VerticalContentAlignment="Center"/>
            <Button x:Name="OutputBtn" Template="{StaticResource RoundCornerBtn}" Grid.Column="1" Grid.Row="1" Margin="5,0,0,0" Height="30" FontSize="14" Background="#FF006561" Foreground="White" Grid.ColumnSpan="2" Content="{Binding LanguageModel.OutputBtn}"/>
            <Button x:Name="ConvertBtn" Template="{StaticResource RoundCornerBtn}" Grid.Row="2" Grid.ColumnSpan="3" Margin="0,7,0,6" FontSize="16" Background="#FF006561" Foreground="White" FontWeight="Bold" Content="{Binding LanguageModel.ConvertBtn}"/>
        </Grid>            
</Grid>

我不知道我是否未能设置我的Bindings来访问LanguageModel实例的属性 或者RaisePropertyChanged()方法以错误的方式实现。 我之前尝试过像Path= LanguageModel.Property那样设置我的Bindings。 我试图将模型属性放在一个可观察的列表中并通过它进行迭代,这也没有用。

此外,当我尝试调试程序并将鼠标悬停在LangaugeModel属性上时,调试器会因StackOverFlow异常而关闭。 现在从Exception我猜我的程序被某个循环陷入某个地方,但我无法找到它。

我希望这个详细到足以理解我的问题。(第一篇文章)

1 个答案:

答案 0 :(得分:1)

请注意,存在在XAML标记中进行本地化的项目(例如wpflocalizeextension.codeplex.com)。你不必自己做。

字符串位于resx文件中:

  • 后备语言:filename.resx
  • 德语:filename.de.resx
  • 法语:filename.fr.resx