C# 在WPF中使用StringFormat通过多重绑定通知并更新源

C# 在WPF中使用StringFormat通过多重绑定通知并更新源,c#,.net,wpf,data-binding,multibinding,C#,.net,Wpf,Data Binding,Multibinding,请分析以下代码段: <TextBox x:Name="TxtBox_CommandInfo" Style="{DynamicResource MetroTextBox}" IsReadOnly="True" Controls:TextBoxHelper.Watermark="This is a textbox" HorizontalAlignment="Left" Margin="0,236,0,0" TextWrapping="Wrap" VerticalAl

请分析以下代码段:

<TextBox x:Name="TxtBox_CommandInfo"  Style="{DynamicResource MetroTextBox}"
    IsReadOnly="True" Controls:TextBoxHelper.Watermark="This is a textbox" 
    HorizontalAlignment="Left" Margin="0,236,0,0" TextWrapping="Wrap"
    VerticalAlignment="Top" Height="154" Width="780" 
    ScrollViewer.HorizontalScrollBarVisibility="Auto" 
    ScrollViewer.VerticalScrollBarVisibility="Auto">
  <TextBox.Text>
    <MultiBinding StringFormat="{}{0} {1} {2}" NotifyOnTargetUpdated="True">
      <Binding  Path="A" />
      <Binding  Path="B" />
      <Binding  Path="C"/>
      <Binding Path="D" Mode="TwoWay" NotifyOnTargetUpdated="True"
          UpdateSourceTrigger="PropertyChanged"/>
    </MultiBinding>
  </TextBox.Text>
</TextBox>

正如您所见,
TxtBox\u CommandInfo
textbox文本(目标)值将仅由
A、B、C
修改/格式化,但更新的文本应通过绑定通知
D
。模型如下:

A、B、C
=>[TexBox.Text]=>
D

问题是C端的相应源代码
D
TxtBox\u CommandInfo.Text
更改时不会得到通知和更新

  • 如果没有任何
    转换器
    如何解决此问题
  • 我是否错误配置了多重绑定设置

  • 它确实需要
    StringFormat
    功能,因此如果不注入转换,我们是否有
    StringFormat
    的替代方案?

    我仍然感到困惑。我不知道你到底是什么意思:

    我在评论中试图解释的是,这里有一个解决方案

    XAML:

    C#(VM):


    为什么虚拟机上的
    D
    属性不只是一个组合了
    a
    +
    B
    +
    C
    的getter呢?完全不清楚您想要的是什么。您的
    文本框是
    只读的
    。不可能更新。任何修改都必须从A、B或C进行。正如slugster在VM中所说的格式D<代码>publin字符串D=>$“{A}{B}{C}”问题已解决。@Buddhikachaturaga您不能在只读文本框上双向绑定可能我不明白您想要什么。您有3个属性A、B和C。您希望在文本框中显示对这些属性的任何修改。该文本框必须更新第四个属性,即D?我说得对吗?如果没有,请修改你的问题,并明确你想要什么?也许是一幅画或一幅画something@BuddhikaChaturanga你完全没有领会我的意思。您不需要绑定就可以将字符串组合回属性中——目标属性可以只包含执行该操作的代码。您正在尝试一个非常简单的复杂解决方案。这里有这么多评论,这表明你需要后退一步,重新评估你的代码。谢谢你的回复//非常感谢兄弟。但有一件事!你用
    A,B,C
    更新了
    D
    ,然后绑定到
    Textbox
    ,但我问的是另一种方法,意思是使用
    多绑定A,B,C
    更新
    Textbox
    ,在
    文本
    被更改后,然后更新
    D
    。我想他想避免虚拟机中的属性A,B,C。不知道为什么,想想,那里的所有财产。。。这是清晰的流程,用户更改三个组合框选择,然后分别更新
    A.B,C
    ,同时
    Textbox文本将使用
    A,B.C
    属性的
    MultiBind
    进行修改,在
    Text
    被修改后,属性
    D
    必须根据
    Text
    值进行更改(文本值不仅包含
    A、B、C
    中的值)。@BuddhikaChaturanga您的每一条评论都让我更加困惑。你所要求的是不可能的。如果文本框为只读,则无法更新任何属性,您必须从VM@FoggyFinder是的。。用户不能在此处键入任何文本,这是必需的。。但是我们需要改变MVVM上的
    textchanged
    场景
     <Grid>
        <StackPanel>
            <ComboBox ItemsSource="{Binding Path=MyTexts}" SelectedItem="{Binding Path=A}" Margin="10"/>
            <ComboBox ItemsSource="{Binding Path=MyTexts}" SelectedItem="{Binding Path=B}" Margin="10"/>
            <ComboBox ItemsSource="{Binding Path=MyTexts}" SelectedItem="{Binding Path=C}" Margin="10"/>
    
            <TextBox Height="80" Margin="10" Text="{Binding Path=D, Mode=OneWay}" IsReadOnly="True" AcceptsReturn="True" TextWrapping="Wrap">
            </TextBox>
        </StackPanel>
    </Grid>
    
     public class MyViewModel : INotifyPropertyChanged
    {
        private string _a;
        private string _b;
        private string _c;
    
        public string A
        {
            get => _a;
            set
            {
                _a = value;
                OnPropertyChanged(nameof(A));
                OnPropertyChanged(nameof(D));
            }
        }
        public string B
        {
            get => _b;
            set
            {
                _b = value;
                OnPropertyChanged(nameof(B));
                OnPropertyChanged(nameof(D));
            }
        }
        public string C
        {
            get => _c;
            set
            {
                _c = value;
                OnPropertyChanged(nameof(C));
                OnPropertyChanged(nameof(D));
            }
        }
        public string D => $"{A} {B} {C}";
    
        public List<string> MyTexts { get; }
    
        public MyViewModel()
        {
            MyTexts = new List<string>() { "FHAKWEFJ AWKEEF AWEKF LAEWKF LAWEF", "AAAAAAAAAAAAAAAAAAAAAA", "BBBBBBBBBBBBBBBBBBBBBBBBB", "EEEEEEEEEEEEEEEEEEEEEEEEE", "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG", "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG" };
        }
    
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        #endregion
    }
    
    <TextBox Height="80" Margin="10" TextChanged="TextBoxBase_OnTextChanged" IsReadOnly="True" AcceptsReturn="True" TextWrapping="Wrap">
       <TextBox.Text>
                    <MultiBinding StringFormat="{}{0} {1} {2}" NotifyOnTargetUpdated="True" Mode="OneWay">
                        <Binding  Path="A" Mode="OneWay"/>
                        <Binding  Path="B"  Mode="OneWay"/>
                        <Binding  Path="C" Mode="OneWay"/>
                    </MultiBinding>
                </TextBox.Text>
     </TextBox>
    
    private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
    {
        if (this.DataContext is MyViewModel dataContext)
            dataContext.D = ((TextBox) sender).Text;
    }
    
        private string _d;
    
        public string D
        {
            get => _d;
            set
            {
                _d = value;
                OnPropertyChanged(nameof(D));
            }
        }