【问题标题】:textbox not updating its value from viewmodel文本框未从视图模型更新其值
【发布时间】:2015-12-21 07:01:36
【问题描述】:

我有一个命令,当单击发送按钮时发送文本。绑定设置为双向,updatesource 触发器设置为 propertychanged。但是文本框的值不会更改为包含在 sendCommand 中的 string.empty,即使该命令能够为新消息获取更新的文本框值。

public class BuddyChatViewModel : BaseViewModel
{
    private string chat;
    public string Chat
    {
        get { return chat; }
        set
        {
            chat = value;
            RaisePropertyChanged();
        }
    }        

    public RelayCommand sendChatCommand { get; private set; }
    string username = "";
    string buddy = "";
    UriStrings url = new UriStrings();
    BuddiesHomeModel buddiesList = new BuddiesHomeModel();
    HttpService http = new HttpService();
    StorageService store = new StorageService();
    string response = "";

    BuddyChatModel buddyChat = new BuddyChatModel();
    List<BuddyChat2Datum> buddychatList = new List<BuddyChat2Datum>();
    BuddyChat2Datum tempDatum = new BuddyChat2Datum();
    private ObservableCollection<BuddyChat2Datum> buddyChatOC = new ObservableCollection<BuddyChat2Datum>();
    public ObservableCollection<BuddyChat2Datum> BuddyChatOC
    {
        get { return buddyChatOC; }
        set
        {
            buddyChatOC = value;
            RaisePropertyChanged();
        }
    }


    private async void sendChatExecute()
    {            
        int i = 0;
        string s = url.buddychatText(username, buddy, chat);
        chat = "";
        response = await http.GetAsync(s);            
        buddyChat = JsonConvert.DeserializeObject<BuddyChatModel>(response);
        buddychatList.Clear();
        for (i = 0; i < buddyChat.data.Count; i++)
        {
            tempDatum.conversation = buddyChat.data[i].conversation;
            tempDatum.datetime = buddyChat.data[i].datetime;
            tempDatum.from = buddyChat.data[i].from;
            tempDatum.to = buddyChat.data[i].to;
            if (tempDatum.from == username)
                tempDatum.isLeft = false;
            else
                tempDatum.isLeft = true;
            buddychatList.Add(tempDatum);
            tempDatum = new BuddyChat2Datum();
        }
        BuddyChatOC.Clear();
        for (i = 0; i < buddychatList.Count; i++)
        {
            BuddyChatOC.Add(buddychatList[i]);
        }
        Navigate<BuddyChatViewModel>(buddychatList);
    }



    #region State Management

    public override void LoadState(object navParameter, Dictionary<string, object> state)
    {
        sendChatCommand = new RelayCommand(sendChatExecute);
        int i = 0;
        base.LoadState(navParameter, state);
        BuddyChatOC.Clear();
        // load test items again; in production this would retrieve the live item by id or get it from a local data cache
        List<BuddyChat2Datum> buddychatList = (List<BuddyChat2Datum>)navParameter;
        //var mes = new MessageDialog(buddychatList.Count.ToString());
        //await mes.ShowAsync();
        for(i=0;i<buddychatList.Count;i++)
        {
            BuddyChatOC.Add(buddychatList[i]);
        }
        username = buddychatList[i-1].username;
        buddy = buddychatList[i-1].buddy;          
    }


    public override void SaveState(Dictionary<string, object> state)
    {
        base.SaveState(state);

    }

    #endregion
}   

}

xml代码:

 <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <ListView x:Name="chatList" HorizontalAlignment="Stretch" ItemsSource="{Binding BuddyChatOC}" ItemTemplateSelector="{StaticResource ChatSelector}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                </Style>
            </ListView.ItemContainerStyle>

        </ListView>
        <RelativePanel Grid.Row="1" Margin="5,10,5,10">
            <TextBox x:Name="sendtext" Margin="0,0,2,0" Text="{Binding Chat, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" RelativePanel.AlignLeftWithPanel="True"  RelativePanel.LeftOf="sendtextbutton"/>
            <Button x:Name="sendtextbutton" Content="Send" Command="{Binding sendChatCommand}"  RelativePanel.AlignRightWithPanel="True" >                    
            </Button>
        </RelativePanel>
    </Grid>

【问题讨论】:

  • 必须执行INotofyPropertyChanged
  • 在 BuddyChatOC 设置器中你应该有 RaisePropertyChanged("BuddyChatOC");
  • 问题不在于 buddychatoc.. 列表视图已正确更新.. 问题在于作为文本框绑定属性的“聊天”字符串

标签: c# xaml binding viewmodel mvvm-light


【解决方案1】:

BuddyChatViewModel 中实现 INotifyPropertyChanged

public class BuddyChatViewModel : INotifyPropertyChanged, BaseViewModel
{
private string chat;
public string Chat
{
    get { return chat; }
    set
    {
        chat = value;
        NotifyPropertyChanged("Chat");
    }
}   


//INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}

}

【讨论】:

    【解决方案2】:

    如果您使用的是 MVVMLight(并且从我假设您使用这个问题的标记方式来看),您需要在 RaisePropertyChanged 调用中指定更改的属性名称。

    这应该适用于您的情况:

    public string Chat
        {
            get { return chat; }
            set
            {
                chat = value;
                RaisePropertyChanged(() => Chat);
            }
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多