2012-10-22 74 views
1

经过几个月的动手WPF,我决定给Caliburn Micro一枪。我有几件事情我无法工作。我先发布代码,请参阅下面我的问题/问题:Caliburn Micro,绑定和通知

public class MainViewModel : PropertyChangedBase 
{ 
    BindableCollection<PlayerProfile> _playerProfiles = staticInfos.Load(); 

    public BindableCollection<PlayerProfile> PlayerProfiles { 
     get { return _playerProfiles; } 
     set { 
      _playerProfiles = value; 
      NotifyOfPropertyChange(() => PlayerList); 
     } 
    } 

    string _tb_AddPlayer; 
    public string TB_AddPlayer { 
     get { return _tb_AddPlayer; } 
     set { 
      _tb_AddPlayer = value; 
      NotifyOfPropertyChange(() => TB_AddPlayer); 
      NotifyOfPropertyChange(() => CanAddPlayer); 
     } 
    } 

    List<string> _pl = new List<string>(); 
    public List<string> PlayerList { 
     get{ 
      foreach (PlayerProfile p in PlayerProfiles) { 
       if (!_pl.Contains(p.Name)) _pl.Add(p.Name); 
      } 
      return _pl;    
     } 
     set { 
      _pl = value; 
      NotifyOfPropertyChange(()=>PlayerList); 
     } 
    } 

    // Dummy Test String 
    string _test; 
    public string Test { 
     get { return _test; } 
     set { 
      _test = value; 
      NotifyOfPropertyChange(() => Test); 
     } 
    } 

    // Button Action 
    public void AddPlayer() { 
     _playerProfiles.Add(new PlayerProfile(TB_AddPlayer)); 
     Test = "Pressed"; 
     NotifyOfPropertyChange(() => PlayerProfiles); 
    } 

    public bool CanAddPlayer { 
     get { return true; } 
     // doesnt work: get { return !string.IsNullOrWhiteSpace(TB_AddPlayer); } 
    } 
} 

所以这里有云:我用的是约束力的公约,即在一个的MainView属性应绑定到相同名称的元素在视图。

  • 首先,注意PlayerList仅仅是一个运动员的PlayerProfiles的名字,这是我创建,因为结合到Combobox的时候,他们不露面,当我命名Combobox PlayerProfiles的名单,但当我通过列表并将其命名为PlayerList时 - 虽然我已覆盖PlayerProfile class中的ToString方法。为什么?这似乎笨拙...(该staticInfos.Load()方法填充PlayerProfiles几个假名字,如果你想知道...)

  • 当我在文本框中键入(称为TB_AddPlayer)的东西,然后按下按钮(称为AddPlayer)测试字符串出现,所以我知道这个动作发生了,但是新名字没有出现在组合框中,但是新名字没有出现在组合框中,但是如果我使用CanAddPlayer属性中的注释行,该按钮从不被启用,而不是如果我开始输入,也不会在文本框失去焦点时使用文本。为什么?

对不起,对于这些基本问题,我已经盯着'Hello World'caliburn示例几个小时,并没有看到我缺少的东西...... Thx。提前!

编辑:这里是的.xaml

<UserControl x:Class="MixGameM8_MVVM.Views.MainView" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:MixGameM8_MVVM.Views"> 

<UserControl.Resources> 
    <Style TargetType="TextBlock" x:Key="TB_A"> 
     <Setter Property="Margin" Value="5,5,5,5" /> 
     <Setter Property="HorizontalAlignment" Value="Center" /> 
     <Setter Property="FontSize" Value="15" /> 
    </Style> 

    <!-- ... Some more of this kind --> 
</UserControl.Resources> 

<Grid> 
    <!-- ... Grid definitions --> 
    <Border Style="{StaticResource Border_A}" Grid.Row="0" Grid.Column="0"> 
     <StackPanel Name="SP_Controls"> 
      <TextBlock Style="{StaticResource TB_A}" Text="Controls"/> 
      <ComboBox Style="{StaticResource CB_A}" Name="PlayerProfiles"/> 
      <StackPanel Orientation="Horizontal"> 
       <TextBox Style="{StaticResource TBox_A}" Name="TB_AddPlayer" MinWidth ="100" /> 
       <Button Style="{StaticResource Button_AddPlayer}" Content="Add Player" Name="AddPlayer" /> 
      </StackPanel> 
     </StackPanel> 
    </Border> 

<!-- ... And some more cells in the grid, one containing the dummy textbox --> 

</Grid> 
</UserControl> 
+0

你可以请你也发布你的'MainView' XAML? – nemesv

回答

3

首先,我想通过删除您PlayerList物业启动,并更新PlayerProfiles属性,像这样:

public BindableCollection<PlayerProfile> PlayerProfiles { 
    get { return _playerProfiles; } 
    set { 
     _playerProfiles = value; 
     NotifyOfPropertyChange(() => PlayerProfiles); 
    } 
} 

接下来,我不会打电话给你查看模型属性,描述它们是如何呈现的,即将TB_AddPlayer更改为AddPlayer(或者更好的是PlayerName,因为它就是这样)。

接下来,如果你打电话给你的ComboBox PlayerProfiles,那么绑定应该通过约定自动发生。在你AddPlayer方法,你要通过你的财产,不支持字段添加新的玩家概况:

变化:

public void AddPlayer() { 
    _playerProfiles.Add(new PlayerProfile(TB_AddPlayer)); 
    Test = "Pressed"; 
    NotifyOfPropertyChange(() => PlayerProfiles); 
} 

到:

public void AddPlayer() { 
    this.PlayerProfiles.Add(new PlayerProfile(this.PlayerName)); 
} 

因为PlayerProfiles是BindableCollection,更改通知将被执行,并且您的ComboBox将被更新。

此外,我总是明确指定您的后台字段的访问修饰符,即private string _playerName;不只是字符串_playerName;

尝试这些更改,并在问题中更新您的代码,如果您仍然有问题。

+0

感谢您的回答!虽然我直接绑定到'PlayerProfiles',但是(我做了通知中的更改),Combobox不显示名称,但是两次(有两个配置文件由Load()方法生成)条目'Can not find view for' Project_MVVM.Models.PlayerProfile”。那是什么意思? – EluciusFTW

+0

另外,我想如果我写'string a ...'和'private string a ...',它们的编译方式完全一样,即省略前缀会自动将其设置为private ,还是我错了? – EluciusFTW

+0

你是对的,但最好是明确并加入'私人'访问修饰符。就你的第一个问题而言,默认情况下,Caliburn.Micro将假定你的集合中的类型是一个视图模型,并且会尝试找到相关的视图(例如PlayerProfile.xaml),并且它会绑定你的PlayerProfile类型到PlayerProfile视图)。但是,由于这不是视图模型类型,因此可以将ComboBox的'DisplayMemberPath'属性设置为PlayerProfile类型的属性,或者创建ComboBox ItemTemplate。 – devdigital

0

我觉得我得到的答案

在您的文本框中使用updatesourcetrigger =属性更改 的可以执行没有更新,因为你没有使用依赖于(或依赖不remeber名称)属性。

组合框未更新会导致您应将其绑定到可绑定集合。

+0

对于所有文本框实例,更新源触发器都被设置为默认情况下使用Caliburn.Micro更改的属性。 – devdigital

+0

不过,我没有那部分工作。现在,当按下按钮时,我正在为Combobox添加一个新玩家,但无论文本框的内容如何,​​玩家都没有名字(即组合框选项中出现更多白线)......为什么? – EluciusFTW

+0

任何人都有一个想法,文本框绑定仍然不工作:-(...所有仍然是在最后的评论。 – EluciusFTW